powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проверка на циклы в иерархической таблице(Головоломка)
61 сообщений из 61, показаны все 3 страниц
Проверка на циклы в иерархической таблице(Головоломка)
    #39998584
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Навеяно другой темой, про constraints и проверку данных на вшивость.

Задана таблица EMPLOYEES с полями employee_id и manager_id типа integer.
Таблица описывает строгую древовидную иерархию, с одним гендиректором наверху.

Как в SQL (или в PL/SQL, чтоб легче) подтвердить правильность древовидной структуры?
Критерии правильности древовидности довольно очевидна но на всякий случай в вики есть определение:

https://ru.wikipedia.org/wiki/Дерево_(структура_данных)
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998585
Фотография Relic Hunter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
select count(*) from employees where manager_id is null
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998586
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL,

На форуме ужн многократно обсуждалось, решения элементарные, а на современных версиях ещё легче. Но ты пиши, посмотрим...
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998589
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Relic Hunter
Код: plsql
1.
select count(*) from employees where manager_id is null



Лаконично. Похоже, что производится подсчет гендиректоров, из предположения что гендиректор помечен null.
Это не единственный способ отметить гендиректора, но вполне рабочий. Для этого manager_id придется сделать nullable, расслабив одно из ограничений.

Этот тест отловит таблицы где нет гендиректоров, или более одного гендиректора. Некоторые вещи он пропустит.

Код: plaintext
1.
2.
3.
4.
5.
6.
Контрпример: следующие таблицы обе вернут (1), но вторая из них не отвечает определению дерева.

EMPLOYEES_GOOD       EMPLOYEES_BAD
emp_id  mgr_id       emp_id  mgr_id
===============================================
  5       0           5       0
  8       5           8       8

У меня пока тоже не получается записать эту задачу на SQL, т.к. мое решение полагается на цикл, а с циклами в SQL туго.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998623
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

проверить что все "узлы" employee_id в дереве и нет циклов?

ps
connect by, with ...

....
stax
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998738
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Некоторые вещи он пропустит.

Код: plaintext
1.
2.
3.
4.
5.
6.
Контрпример: следующие таблицы обе вернут (1), но вторая из них не отвечает определению дерева.

EMPLOYEES_GOOD       EMPLOYEES_BAD
emp_id  mgr_id       emp_id  mgr_id
===============================================
  5       0           5       0
  8       5           8       8


Пропустит, но не это. Это предотвращается а не проверяется. Например через FBI на EMPLOYEES(1 / (EMPNO - MGR)) или через calculated column X = EMPNO - MGR плюс check constraint CANT_SELFREPORT на X != 0.

SY.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998746
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
НеофитSQL
Некоторые вещи он пропустит.

Код: plaintext
1.
2.
3.
4.
5.
6.
Контрпример: следующие таблицы обе вернут (1), но вторая из них не отвечает определению дерева.

EMPLOYEES_GOOD       EMPLOYEES_BAD
emp_id  mgr_id       emp_id  mgr_id
===============================================
  5       0           5       0
  8       5           8       8


Пропустит, но не это. Это предотвращается а не проверяется. Например через FBI на EMPLOYEES(1 / (EMPNO - MGR)) или через calculated column X = EMPNO - MGR плюс check constraint CANT_SELFREPORT на X != 0.

SY.
а просто чек на empno != mgr?
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998758
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне приятно, что есть желающие размять мозги и возможно, блеснуть кодом.

Действительно, можно ввести проверку на eid != mid (давайте сократим эти поля employee_id и manager_id).
Такая проверка исключит тривиальные циклы. Но пропустит более длинные.

Контрпример: цикл из двух, не ловится вышеописанной проверкой.

Код: plaintext
1.
2.
3.
4.
5.
EMPLOYEES_GOOD       EMPLOYEES_BAD
emp_id  mgr_id       emp_id  mgr_id
===============================================
  5       0           5       0
  8       5           8       3
  3       5           3       8

В этом контрпримере, в "хорошей" таблице строчки 2-3 подчинены гендиректору, а в "плохой" таблице - друг другу (цикл).
Цикл может быть из трех и более - нужно ловить все.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998761
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кит северных морей
а просто чек на empno != mgr?


Brain fart

SY.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998767
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL


В этом контрпримере, в "хорошей" таблице строчки 2-3 подчинены гендиректору, а в "плохой" таблице - друг другу (цикл).
Цикл может быть из трех и более - нужно ловить все.


А это без сериализации не предотвращается а проверить можно только полным проходом по дереву.

SY.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998776
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax
НеофитSQL,

проверить что все "узлы" employee_id в дереве и нет циклов?

ps
connect by, with ...

....
stax


Чувствуется человек с опытом работы - первым делом уточнил условия задачи.

Дополнение к первому сообщению, более конкретные условия задачи:
1) гендиректор обозначается manager_id (mid) = null
2) пустая таблица не считается деревом
3) таблица из одного и более элементов может быть деревом (только гендиректор - считать деревом)
3) в дереве ровно один ген директор
4) циклы в графе запрещены - у дерева не бывает циклов
5) каждый сотрудник должен быть напрямик или через других подчинен гендиректору
6) результат функции или запроса должен говорить "дерево" или "не дерево" (true/false, 1/0, на усмотрение)
7) код должен отрабатывать за конечное время, быстрее - лучше

Я заметил что в коммерческих решениях зачастую вершина дерева помечается как mid=eid, а не как mid=null.
Думаю, что это делается с целью усиления constraints, тогда mid можно определить non-nullable внешний ключ.
Если к этому добавить запрет на mid=eid для INSERT, будет невозможно испортить дерево при добавлении сотрудников.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998780
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL

Цикл может быть из трех и более - нужно ловить все.

connect by нельзя пльзоваться?

....
stax
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998791
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тривиально: пройтись по всем записям, выстраивая иерархию от подчиненного к менеджеру.
Обработать exception "connect-by loop in user data" либо проконтролировать соответствующий флаг.
Отобрать листья.
Сгруппировать листья и убедиться, что результатом группировки является единственная запись и эта запись соответствует корню иерархии.
Фсьо.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998810
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно пользоваться connect by, и любыми другими встроенными средствами Оракл.

Если там есть встроенная команда проверки всего дерева, то это было бы самым правильным решением.

Кстати, я не знал про существование connect by до этого момента, сейчас читаю как эта конструкция обрабатывает циклы.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998814
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемый, уже несколько дней наблюдаю за Вашим творчеством.
Не скрою,увлекательно.
Продолжайте пожалуйста.
Только огромная просьба: пожалуйста, ни в коем случае не изучайте выбранный технологический стек, не читайте документацию - от этого Ваши сообщения могут существенно потерять в лулзах.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998824
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Если там есть встроенная команда проверки всего дерева,

В множестве типа "куча" нет деревьев, но можно хранить записи, имеющие логические ссылки на соседние. На этом всё.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998828
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous
Тривиально: пройтись по всем записям, выстраивая иерархию от подчиненного к менеджеру.
Обработать exception "connect-by loop in user data" либо проконтролировать соответствующий флаг.
Отобрать листья.
Сгруппировать листья и убедиться, что результатом группировки является единственная запись и эта запись соответствует корню иерархии.
Фсьо.


Это звучит как решение. Вряд ли я такое сегодня смогу написать на SQL.

А вот connect-by/noloop - очень полезная штука, я о ней до этого не знал.
С этим оператором задача упрощается в разы.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998834
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL

С этим оператором задача упрощается в разы.


Не упрощается. В многопользовательском режиме (что есть стандарт) такая проверка (CONNECT BY) ничего не гарантирует. Без сериализации тут не обойтись.

SY.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998837
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQLКак в SQL (или в PL/SQL, чтоб легче) подтвердить правильность древовидной структуры?

Составной ключ id+уровень иерархии, соответствующий FK и сверху chеck, проверяющий уровень
иерархии менеджера выше, чем у работника.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998838
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SY,

Да что ж вы делаете-то... Остановитесь! Сейчас ещё одна же тема появится, теперь про уровни изоляции транзакций и мини-откаты... Прямо галопом по европам...
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998841
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

НеофитSQLКак в SQL (или в PL/SQL, чтоб легче) подтвердить правильность древовидной структуры?

Составной ключ id+уровень иерархии, соответствующий FK и сверху chеck, проверяющий уровень
иерархии менеджера выше, чем у работника.


Идея понятна, но уровень иерархии не определен для циклов.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998844
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQLуровень иерархии не определен для циклов.

В дереве не существует циклов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998853
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY

В многопользовательском режиме (что есть стандарт) такая проверка (CONNECT BY) ничего не гарантирует. Без сериализации тут не обойтись.
SY.


В многопользовательском режиме CONNECT BY исполняется по-другому, и ему нельзя доверять?
Я написал следующее условие, которое true если дерево, и false если не дерево.
Оно использует connect by, оно сломается и даст неверные данные в многопользовательском режиме?
Или вы говорите о ситуации, когда таблица меняется во время исполнения проверок?
Если так, то добавим условие что таблицу считать статической на время проверки (напр., копия)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
(select  count(*)
   from  EMPLOYEES
   start with mid is null
 connect by
 nocycle
   prior eid = mid)
 =(select count(*) from EMPLOYEES) 
and 
(select count(*) from EMPLOYEES where mid is null) = 1
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998857
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

НеофитSQLуровень иерархии не определен для циклов.

В дереве не существует циклов.


Действительно. У дерева нет циклов, и ровно один корень.
Условие этой головоломки - определить представляет ли таблица правильное дерево.

Ваше предложенное решение начинается с "предположим, что это правильное дерево, где определен уровень иерархии.." :)
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998860
dmdmdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL

В многопользовательском режиме CONNECT BY исполняется по-другому, и ему нельзя доверять?


Поскольку в однопользовательском вы будете работать исчезающе редко, лучше сразу прочитать Oracle Database Concepts, о чем вам уже несколько дней повторяют, и выкинуть свой устав, придя в этот монастырь.

и не выдумывать фантастических ситуаций

таблицу считать статической на время проверки (напр., копия)
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998865
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQLУсловие этой головоломки - определить представляет ли таблица правильное дерево.

Если создание описанных ограничений на реальной таблице закончится с ошибкой их проверки -
дерево неправильное.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998866
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

НеофитSQLУсловие этой головоломки - определить представляет ли таблица правильное дерево.

Если создание описанных ограничений на реальной таблице закончится с ошибкой их проверки -
дерево неправильное.


Так тоже можно.
Начать с предположения что дерево правильное, попробовать применить операции которые вылетят на плохом дереве, и словить exception, который скажет об определенном аспекте неправильности дерева. Это теория; пока кода нет, море по колено :)

На практике, вместо вылета кода можно попасть в бесконечный цикл, вычисляя уровень иерархии на цикле.
Бесконечный цикл не соответствует постановке задачи (запрос/функция должна вернуться в конечное время).
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998873
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

про бесконечный цикл вам рассказали во второй строке вот этого сообщения:

andrey_anonymous
Тривиально: пройтись по всем записям, выстраивая иерархию от подчиненного к менеджеру.
Обработать exception "connect-by loop in user data" либо проконтролировать соответствующий флаг.
Отобрать листья.
Сгруппировать листья и убедиться, что результатом группировки является единственная запись и эта запись соответствует корню иерархии.
Фсьо.


Речь здесь идет об ошибке времени выполнения, т.е. фетча.
Альтернативно, вместо генерации ошибки, в рекурсивном варианте запроса можно заказать пометку зацикливающихся строк.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998885
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Обкатав мое решение на нескольких таблицах разной степени поломанности,
я комфортабельно его размещаю как одно из возможных правильных.
Вчера я не знал, как это написать в виде запроса, только алгоритмически с PL/SQL.
Сегодня, благодаря участникам форума я освоил один из вариантов connect-by.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
-- проверка на древесность:
-- 1) убедиться что ровно один корень (это также отсечет пустые таблицы)
-- 2) начиная с корня, посчитать всех подчиненых. Если совпало с размером таблицы - это дерево!
-- 3) "nocycle" здесь не требуется, этот селект защищен от встречи с циклами
-- 
lock table EMPLOYEES in share mode; -- защитить проверку от реорганизации в головоломке :)
select 'Дерево' as answer 
from dual
where (select count(*) from EMPLOYEES where mid is null) = 1 and
      (select count(*) from EMPLOYEES)  = 
      (select count(*) from EMPLOYEES
        start with mid is null
      connect by prior eid = mid);



Мне неизвестна скорость данного решения, и нет возможности проверить эмпирически.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998896
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
Код: plsql
1.
проверка на древесность

тихий ужас...
НеофитSQL
Код: plsql
1.
lock table EMPLOYEES in share mode; -- защитить проверку от реорганизации в головоломке :)

мда. ну пусть хотя бы так пока...

НеофитSQL
1) убедиться что ровно один корень (это также отсечет пустые таблицы)

это можно сделать навесив уникальный ключ на decode(mid,null,1)
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998914
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQLНа практике, вместо вылета кода можно попасть в бесконечный цикл, вычисляя уровень
иерархии на цикле.

Нельзя если запрос составлен правильно. Ну а кривыми руками неофита можно что угодно колом
поставить.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998931
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подведем итоги.

Головоломка решена, одним из способов. Были поползновения сделать вклад от некоторых участников, но побрюзжав с галерки, они так и не родили ни единой строчки рабочего кода, сберегая силы. Несомненно, что справились бы одной левой если б только..

connect-by - отличная штука, и даже умеет обрабатывать циклы, когда требуется.

Как было неоднократно упомянуто уважаемыми коллегами, использование constraints позволяет сохранить ссылочную целостность, хотя бы частично. Например, в головоломке используется таблица EMPLOYEES такого сорта:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create table EMPLOYEES
(
  eid INTEGER not null,
  mid INTEGER
)
tablespace USERS
...
alter table EMPLOYEES
  add constraint PK__EMPLOYEES_EID primary key (EID)
  using index 
...
alter table EMPLOYEES
  add constraint FK__EMPLOYEES_MID foreign key (MID)
..
-- Create/Recreate check constraints 
alter table EMPLOYEES
  add constraint NOSELFREPORT  check (mid != eid);
alter table EMPLOYEES
  add constraint ONE_CEO       check (/*селект=1 тут нельзя*/);



Уникальные ID? сделано через PK
Контроль ссылок менеджера? сделано через FK (но позволен null, для гендиректора)
Защита от тривиальных циклов? Есть, проверка NOSELFREPORT
Защита от лишних гендиректоров? Тут проблема, синтакс не позволяет select,
поэтому такую проверку скорее всего делают в триггере.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998932
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQLпоэтому такую проверку скорее всего делают в триггере.

Нет, не делают, потому что и там она совершенно неработоспособна.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998934
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Молодец. А практический смысл у этой задачи какой?
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998935
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL


Мне неизвестна скорость данного решения, и нет возможности проверить эмпирически.


табличка не дерево
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SQL> ed
Wrote file afiedt.buf

  1  with EMPLOYEES as (
  2  select 0 eid , null mid from  dual union all
  3  select 1,0 from dual union all
  4  select 3,1 from dual union all
  5  select 4,0 from dual union all
  6  select 3,4 from dual union all
  7  select 5,3 from dual union all
  8  select 8,9 from dual )
  9  select 'Дерево' as answer
 10  from dual
 11  where (select count(*) from EMPLOYEES where mid is null) = 1 and
 12        (select count(*) from EMPLOYEES)  =
 13        (select count(*) from EMPLOYEES
 14          start with mid is null
 15*       connect by prior eid = mid)
SQL> /

ANSWER
------
Дерево



.....
stax
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998949
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

точно, это не дерево. Но нарушена ссылочная целостность, которая .... погодите... так и не была указана в условиях задачи.
Контрпример принимается - алгоритм не все ловит. Наметаный у вас, однако, глаз!

Оказывается дело даже не в желтой строчке, мой алгоритм отлавливает несуществующих менеджеров.
Дело в том, что нарушена уникальность работников (номер 3 есть дважды), и вот это привело к +1/-1.

Использую ваш контрпример, чтобы добавить еще одно условие - уникальность eid и его наличие.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
with EMPLOYEES as (
  select 0 eid , null mid from  dual union all
  select 1,0 from dual union all
  select 3,1 from dual union all
  select 4,0 from dual union all
  select 3,4 from dual union all
  select 5,3 from dual union all
  select 8,9 from dual )
  select 'Дерево' as answer
  from dual
   where (select count(*) from EMPLOYEES where mid is null) = 1 and
         (select count(*) from EMPLOYEES where eid is null) = 0 and
         (select count(*) from EMPLOYEES)  = 
         (select count(*) from (select distinct eid from EMPLOYEES)) and 
         (select count(*) from EMPLOYEES)  =
         (select count(*) from EMPLOYEES
           start with mid is null
         connect by prior eid = mid)
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998953
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL


В многопользовательском режиме CONNECT BY исполняется по-другому, и ему нельзя доверять?


Похоже у тебя нет понятия что такое многопользовательский режим. Если Петя и Вася открыли один и тот-же файл в notepad Петя не видит Васины изменения а Вася Петины. То же и в Oracle. Петя поменял mgr Маши на себя но еще не закоммитил а в это время Вася поменял Петиного mgr на Машу. Оба запустили проверку и все пучком ибо Петя не видит Васины изменения а Вася Петины хотя есть цикл. И без сериализации тут никак.

SY.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998961
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НеофитSQL
Головоломка решена
не решена. И впредь читай правила форума и давай адекватное название топику.
НеофитSQL
Были поползновения сделать вклад от некоторых участников, но побрюзжав с галерки, они так и не родили ни единой строчки рабочего кода, сберегая силы.Несомненно, что справились бы одной левой если б только..
пиши-пиши-пиши - доки не читай, поиском не пользуйся...
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998970
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Адекватные решения известны и сто раз на форуме озвучивались. Самое правильное - использовать единую точку входа, т.е создать процедуру и использовать ее.

Простой пример:
тестовая табличка с данными
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table t(
   id int, 
   parent_id int, 
   constraint t_pk primary key(id), 
   constraint t_parent_fk foreign key (parent_id) references t(id) 
)
/
create index t_ix_par on t(parent_id,id)
/
insert into t select level,nullif(level,1)-1 from dual connect by level<=5;
commit;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SQL> select * from t order by id;

        ID  PARENT_ID
---------- ----------
         1       NULL
         2          1
         3          2
         4          3
         5          4


пример процедуры для изменения ссылки на родительскую запись
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
create or replace procedure update_parent(pID int, pNewParent int) as
  cnt int;
  -- connect_by in user data:
  e_cycle exception;
  pragma exception_init(e_cycle, -1436 );
  
  procedure lock_parents(pLockID in int)
  as
     parents sys.odcinumberlist;
     cr sys_refcursor;
  begin
      select id
         bulk collect into parents
      from t
      start with id=pLockID
      connect by prior parent_id = id;

      open cr for select * from t where id in (select * from table(parents)) for update;
  end;
begin
   -- разрешаем иметь несколько ROOTs:
   if pNewParent is not null then
      -- залочим будущих родителей
      lock_parents(pNewParent);

      -- проверим на iscycle:
      select count(*)
         into cnt
      from t
      where connect_by_iscycle = 1
      or pID = id
      start with id=pNewParent
      connect by nocycle prior parent_id = id;

      if cnt>0 then
         raise e_cycle;
      end if;
   end if;
   -- update если все ок:
   update t set parent_id=pNewParent where id=pID;
end;
/


Пример обновлений:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
SQL> select * from t order by id;

        ID  PARENT_ID
---------- ----------
         1
         2          1
         3          2
         4          3
         5          4

SQL> exec update_parent(3,5);
BEGIN update_parent(3,5); END;

*
ERROR at line 1:
ORA-01436: CONNECT BY loop in user data
ORA-06512: at "XTENDER.UPDATE_PARENT", line 36
ORA-06512: at line 1

SQL> exec update_parent(3,1);

PL/SQL procedure successfully completed.

SQL> select * from t order by id;

        ID  PARENT_ID
---------- ----------
         1
         2          1
         3          1
         4          3
         5          4

5 rows selected.



Другое решение (крайне не рекомендуемое из-за потенциальной несогласованности) - использовать materialized view on commit c проверкой:
создаем функцию с проверкой
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
create or replace function check_parents(pID in int) return int deterministic as
  -- connect_by in user data:
  e_cycle exception;
  pragma exception_init(e_cycle, -1436 );

  function check_parents(pLockID in int) return int
  as
  cnt int;
     parents sys.odcinumberlist;
  begin
      -- проверим на iscycle:
      select count(*) into cnt
      from t
      where connect_by_iscycle = 1
      start with id=pLockID
      connect by nocycle prior parent_id = id;

      return cnt;
  end;
begin
   if check_parents(pID) >0 then
      raise e_cycle;
   end if;
   return 1;
end;
/

создаем materialized view
Код: plsql
1.
2.
3.
4.
5.
6.
create materialized view log on t with rowid, primary key;
create materialized view t_mv 
refresh complete on commit
as
select check_parents(id) chk,id,parent_id from t
/

пример обновлений
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
SQL> select * from t order by id;

        ID  PARENT_ID
---------- ----------
         1
         2          1
         3          2
         4          3
         5          4

5 rows selected.

SQL> update t set parent_id=5 where id=3;

1 row updated.

SQL> select * from t order by id;

        ID  PARENT_ID
---------- ----------
         1
         2          1
         3          5
         4          3
         5          4

5 rows selected.

SQL> commit;
commit
*
ERROR at line 1:
ORA-12008: error in materialized view or zonemap refresh path
ORA-01436: CONNECT BY loop in user data
ORA-06512: at "XTENDER.CHECK_PARENTS", line 13
ORA-06512: at "XTENDER.CHECK_PARENTS", line 32


SQL> select * from t order by id;

        ID  PARENT_ID
---------- ----------
         1
         2          1
         3          2
         4          3
         5          4

5 rows selected.

между проверкой и коммитом может успеть пройти чужой коммит. Такая же хрень будет и с триггерной проверкой.

Итого: без блокировки родительских строк 100% обеспечить надежность проверки нельзя
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998972
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY
НеофитSQL


В многопользовательском режиме CONNECT BY исполняется по-другому, и ему нельзя доверять?


Похоже у тебя нет понятия что такое многопользовательский режим. Если Петя и Вася открыли один и тот-же файл в notepad Петя не видит Васины изменения а Вася Петины. То же и в Oracle. Петя поменял mgr Маши на себя но еще не закоммитил а в это время Вася поменял Петиного mgr на Машу. Оба запустили проверку и все пучком ибо Петя не видит Васины изменения а Вася Петины хотя есть цикл. И без сериализации тут никак.

SY.


Это объяснение на доступном мне языке. Пример внятный, но он относится к писакам, а не к читакам.
Я по неопытности перепугался что мне вася/петя могут таблицу изменить во время исполнения моего запроса.
Но, почитав документацию, успокоился - Оракл гарантирует что моему запросу на лету таблицу не изменят,
поэтому программистам читающего кода о таких вещах беспокоиться не приходится.
Тем более в головоломке на сообразительность.

Про сериализацию нашел материал, почитаю как Оракл разрешает коммит- и другие конфликты. Спасибо
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998981
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
virtual columns + check constraint основанные на такой функции будут вызывать ORA-04091: table is mutating, trigger/function may not see it:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
create or replace function check_parents_virtual(pID in int, pParentId in int) return int deterministic as
  -- connect_by in user data:
  e_cycle exception;
  pragma exception_init(e_cycle, -1436 );

  function check_parents(pLockID in int) return int
  as
  cnt int;
     parents sys.odcinumberlist;
  begin
      -- проверим на iscycle:
      select count(*) into cnt
      from t
      where connect_by_iscycle = 1
      start with id=pLockID
      connect by nocycle prior parent_id = id;

      return cnt;
  end;
begin
   if check_parents(pID) >0 then
      raise e_cycle;
   end if;
   return 1;
end;
/
alter table t
  add chk number(1) generated always as (check_parents_virtual(id,parent_id));
alter table t
  add constraint t_chk check (chk=1) INITIALLY DEFERRED DEFERRABLE;
 
create index t_ix_chk on t(chk);

Код: plsql
1.
2.
3.
4.
5.
6.
7.
SQL> update t set parent_id=5 where id=3;
update t set parent_id=5 where id=3
*
ERROR at line 1:
ORA-04091: table XTENDER.T is mutating, trigger/function may not see it
ORA-06512: at "XTENDER.CHECK_PARENTS_VIRTUAL", line 11
ORA-06512: at "XTENDER.CHECK_PARENTS_VIRTUAL", line 27

...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998983
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL

Я по неопытности перепугался что мне вася/петя могут таблицу изменить во время исполнения моего запроса.
Но, почитав документацию, успокоился - Оракл гарантирует что моему запросу на лету таблицу не изменят


Ты, по неопытности, не пугашлся ибо лезешь напролом не осозновая опасностей. "Оракл гарантирует что моему запросу на лету таблицу не изменят" - это и есть statement level read consistency, a.k.a. запрос видит данные так как они были на момент запроса. Т.е. изменения даже закоммиченные но после твоего запроса проверки целостности дерева не увидит и цикл прошляпит.

SY.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998984
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender

Итого: без блокировки родительских строк 100% обеспечить надежность проверки нельзя


Много красивого и интересного кода, с удовольствием посмотрел, кое-что понял.

SY и xtender подняли тему важную тему сериализации/блокировки, важную для сохранения целостности данных.

Мое мнение по этому поводу: программисты которые пишут только читающий код (те же запросы), имеют полный иммунитет,
и вправе писать запросы как если бы они были единственным пользователем этой базы.

select count(*) from TABLE всегда даст правильное число строчек для того контекста, в котором она вызвана.
Для писаки Васи это пять, для писаки Пети восемь, а для читаки Нины - три.

Вся ответственность за контролем доступа, избеганием дедлоков и другими интересными вещами лежит только на коде,
который пишет в базу, и больше ни на ком другом.

Я не представляю ситуацию, когда читающий код возьмет лок, без всякого намерения писать в базу.
Случай (SELECT ... FOR UPDATE) сюда не входит, читаки его не вызывают.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998995
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY
НеофитSQL

Я по неопытности перепугался что мне вася/петя могут таблицу изменить во время исполнения моего запроса.
Но, почитав документацию, успокоился - Оракл гарантирует что моему запросу на лету таблицу не изменят


Ты, по неопытности, не пугашлся ибо лезешь напролом не осозновая опасностей. "Оракл гарантирует что моему запросу на лету таблицу не изменят" - это и есть statement level read consistency, a.k.a. запрос видит данные так как они были на момент запроса. Т.е. изменения даже закоммиченные но после твоего запроса проверки целостности дерева не увидит и цикл прошляпит.

SY.


"Чукча не писатель, чукча читатель".

У читающего кода нет никаких обязанностей по поводу чужих контекстов. Поэтому они никогда не берут локи.
Соответственно, авторы пишущего кода должны понимать что даже если их контекст зеленый, это не гарантирует безопасность их коммита, потому при отсутствии сериализации другой коммит мог влезь. И ты меня хочешь об этом предостеречь.

Это интересная и сложная тема, с которой я буду разбираться когда начну писать в таблицы.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39998999
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
размещаю как одно из возможных правильных.

Ну раз размещаете...
то вот Вам еще одно "возможно правильное" :)
Я обычно в таких ситуациях накидываю 5-6 вариантов, но сегодня что-то слишком много смеялся.
Код: plsql
1.
2.
3.
4.
5.
select coalesce(decode(count(count(e.mid)), 1, 'Дерево'), 'Не дерево') "Дерево?"
 from EMPLOYEES e
connect by nocycle eid = prior mid 
group by mid
having max(connect_by_isleaf) = 1


Вообще тут есть давнее правило:
- задающий вопрос публикует тестовые данные, ожидаемый результат и свою попытку решить задачу
- загадывающий "пятничную задачку" изначально знает ответ

Примите во внимание - и коллеги не будут обходиться одними лишь ехидными комментариями.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999008
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
select count(*) from TABLE всегда даст правильное число строчек для того контекста, в котором она вызвана.

Чтите концепты ибо они рулез.
Умолчательный уровень изоляции делает Ваше утверждение в общем случае не верным, если Вы выдаете несколько запросов подряд.
К примеру, следующий за select count(*) запрос может зависеть от полученного результата, но "контекст" (на самом деле точка согласования, контекст в oracle - это другое) у него будет уже иной.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999024
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous
НеофитSQL
select count(*) from TABLE всегда даст правильное число строчек для того контекста, в котором она вызвана.

Чтите концепты ибо они рулез.
Умолчательный уровень изоляции делает Ваше утверждение в общем случае не верным, если Вы выдаете несколько запросов подряд.
К примеру, следующий за select count(*) запрос может зависеть от полученного результата, но "контекст" (на самом деле точка согласования, контекст в oracle - это другое) у него будет уже иной.


Резонно. Я с этим не сталкивался, но из похожих соображений не так давно переделал код из такого:

Код: plsql
1.
2.
3.
4.
5.
-- ожидается 0 или 1. если 1, обработать
if (select count(*) from tbl where <condition>) = 1 then
begin
     select col1 into var1 from tbl where <condition>;
    ....



в код, где ловил exception. Не было уверенности что эти два селекта вызвались бы на одном и том же контексте точке согласования.

Я ожидаю много интересного когда потребуется делать изменения в базу.
Благо, в моем коллективе есть опытные кодеры.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999027
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Код: plsql
1.
2.
3.
4.
5.
-- ожидается 0 или 1. если 1, обработать
if (select count(*) from tbl where <condition>) = 1 then
begin
     select col1 into var1 from tbl where <condition>;
    ....


Один из самых дурных антипаттернов в моем личном рейтинге.
Если уж очень-очень надо , то существование записи лучше проверять
Код: plsql
1.
2.
3.
for i in (select null from dual where exists(select null from tbl where <condition>)) loop
 -- делаем что-то полезное при существовании записи, отвечающей условиям
end loop;


но это тоже не фонтан.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999036
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Последняя попытка.


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
DROP TABLE TBL PURGE
/
CREATE TABLE TBL(
                 EMPNO VARCHAR2(10),
                 MGR VARCHAR2(10)
                )
/
INSERT
  INTO TBL
  VALUES(
         'BOSS',
         NULL
        )
/
INSERT
  INTO TBL
  VALUES(
         'VASYA',
         'BOSS'
        )
/
INSERT
  INTO TBL
  VALUES(
         'PETYA'
         'BOSS'
        )
/
INSERT
  INTO TBL
  VALUES(
         'MASHA',
         'BOSS'
        )
/
COMMIT
/




Имеем:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SQL> SELECT  *
  2    FROM  TBL
  3  /

EMPNO      MGR
---------- ----------
BOSS
MASHA      BOSS
PETYA      BOSS
VASYA      BOSS

SQL>



Сессия 1:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
SQL> UPDATE TBL
  2     SET MGR = 'VASYA'
  3     WHERE EMPNO = 'MASHA'
  4  /

1 row updated.

SQL>-- Проверяем на циклы
SQL> SELECT  *
  2    FROM  TBL
  3    CONNECT BY MGR = PRIOR EMPNO
  4  /

EMPNO      MGR
---------- ----------
PETYA      BOSS
VASYA      BOSS
MASHA      VASYA
MASHA      VASYA
BOSS
PETYA      BOSS
VASYA      BOSS
MASHA      VASYA

8 rows selected.

SQL>



Все пучком. В это же время сессия 2:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
SQL> UPDATE TBL
  2     SET MGR = 'MASHA'
  3     WHERE EMPNO = 'VASYA'
  4  /

1 row updated.

SQL>-- Проверяем на циклы
SQL> SELECT  *
  2    FROM  TBL
  3    CONNECT BY MGR = PRIOR EMPNO
  4  /


EMPNO      MGR
---------- ----------
MASHA      BOSS
VASYA      MASHA
PETYA      BOSS
VASYA      MASHA
BOSS
MASHA      BOSS
VASYA      MASHA
PETYA      BOSS

8 rows selected.

SQL>



Все пучком и обе сессии со спокойной совестью делают commit. В результате имеем:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SQL>-- Проверяем на циклы
SQL> SELECT  *
  2    FROM  TBL
  3    CONNECT BY MGR = PRIOR EMPNO
  4  /
ERROR:
ORA-01436: CONNECT BY loop in user data



no rows selected

SQL>



SY.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999039
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
Последняя попытка.


Соломон, не надо нагнетать.
ТС не ставил задачу "обеспечить целостность".
Он ставил задачу "проконтролировать, что в таблице дерево" на предмет "поучиться sql-ить".
И даже пробовал отбиться от ревнителей посредством блокировки :)
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999050
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
virtual columns + check constraint основанные на такой функции

Тут уместнее доменный индекс, кмк.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999056
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous


ТС не ставил задачу "обеспечить целостность".


А, вот она, магическая формулировка с помощью которой можно достучаться к экспертам.

Соломон, я хорошо понял (со второго раза, когда появились петя и маша) про опасности одновременно пишущих сессий,
когда два отдельно ненарушающих действия (заменить скамейку и покрасить скамейку) приводят к нежелаемому результату, что скамейку покрасили, а потом выбросили.

У меня действительно нет задачи обеспечить целостность ни в головоломке (она read-only), ни в моей работе в настоящее время.
Когда я больше узнаю про механизмы синхронизации, и как они уже применяются в существующем коде, я смогу общаться на эту тему более полно. На некоторое время, это будет сознательно вне моей сферы.

Код "последней попытки" я прочитал, все понятно. Спасибо.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999158
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
virtual columns + check constraint основанные на такой функции будут
Саян, выглядит так, что, по-твоему, иногда можно (т.е. ты бы мог посоветовать) обманывать Oracle, декларируя детерминированной функцию, которая таковой по своей сути не является. И что таковой обман не является, на самом деле, обманом себя.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999175
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL

точно, это не дерево. Но нарушена ссылочная целостность, которая .... погодите...
---
Дело в том, что нарушена уникальность работников (номер 3 есть дважды)


eid=3 работает на два проекта, "Astra" менеджер eid=1 и "Lada" менеджер eid=4

....
stax
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999191
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic
xtender
virtual columns + check constraint основанные на такой функции будут
Саян, выглядит так, что, по-твоему, иногда можно (т.е. ты бы мог посоветовать) обманывать Oracle, декларируя детерминированной функцию, которая таковой по своей сути не является. И что таковой обман не является, на самом деле, обманом себя.

Хм..., я бы отдал голос за то, что иногда можно .

Это не обман, а элемент декларации, т.е. интерфейса, значимого для SQL-машины.

В этом отношении, будь я SQL-машиной, я бы так разработчику говорил - это твое дело, разработчик.
Раз ты делаешь это, я верю в то, что понимаешь, что делаешь.
Да, такие функции можно и в индекс "вставить".
А вот обманываешь ты при этом себя, или нет - это не технический для меня вопрос,
а вопрос твоего образования.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999199
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
А вот обманываешь ты при этом себя, или нет - это не технический для меня вопрос,
а вопрос твоего образования.
Ты уверен, что понимаешь, что такое детерминированная функция? Та, которая и через год возвращает одно и то же значение при одних и тех же входных параметрах независимо от того, как изменялись какие бы то ни было данные.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999208
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

это не математика, это техника, в которой с математикой обходятся применяя "инженерный подход".

И это... уверенность в понимании может приводить и приводит,
как к катастрофическим ошибкам, так и к отказам от рабочих решений.

В военное время уверенное понимание может заканчиваться расстрелом перед строем.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999530
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я декларировал функции deterministic для обработки строчек, например.

Согласно докам, это позволяет оптимизатору сохранить результат, и не вызывать функцию много раз с одним и тем же параметром.

Только что проверил, так и есть (функция fPrint(s1,s2) заявлена deterministic, возвращает первый параметр.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SQL> SET SERVEROUTPUT ON
SQL> select 'ret=' || fPrint( 'one', 'two' ) as col1 from TABLE_3ROWS
  2  /
COL1
--------------------------------------------------------------------------------
ret=one
ret=one
ret=one
one two
SQL>



Убрал deterministic, снова вызывается три раза.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999535
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Elic,

Ты говоришь про идеальный мир или про реальный? В реальном мире даже иногда надо. Только надо знать как именно deterministic работает.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999619
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
В реальном мире даже иногда надо. Только надо знать как именно deterministic работает.
И каждому нео нужно это рекламировать? Выглядит, в лучшем случае, как медвежья услуга.
xtender
Ты говоришь про идеальный мир или про реальный?
Реальный мир таков, что твои кэйсы крайне редко подходят другим.
...
Рейтинг: 0 / 0
Проверка на циклы в иерархической таблице(Головоломка)
    #39999621
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
даже иногда надо.
Кстати, никакая "текущая необходимость" не сделает говно-код или говно-решения образцом для подражания. За это может быть только стыдно, что пока сейчас оно как бы работает.
...
Рейтинг: 0 / 0
61 сообщений из 61, показаны все 3 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проверка на циклы в иерархической таблице(Головоломка)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]