Привет всем. Начал юзать эту конструкцию. Перед началом были вопросы они решились. Но закралось смутное сомнение что будет ошибка. Поговорил с DY. Он сказал нафиг серверу хранить то что он выбрал, он не хранит то что отдал по сиквелу. Ну думаю логично, но все же хотелось бы в некоторых случаях чтобы дубликаты не выпадали. Ситуация такая если развернуть дерево в обратную сторону и сложжить его с другим деревом, то получаем рекурсию с бесконечностью.
Для сиквела не в процедуре или триггере всебы ни чего. Но сегодня меня чуть не порвали сервер в упор сжирал память и вылетал с "Unable to allocate memory from operating system.". Я сразу сообразил что виновата рекурсия. Получается при работе в триггере WITH всеже хранит данные а не тупо их выкидывает. Значит можно привязать к WITH еще и типа [DISTINCT col, ...] Проблема вылезла из особого принципа работы производста. Не возможно подсчитать себестоимость если товар для производства в самом акте производства. Для этого ставится табу на такой ввод данных. В результате получаем. WITH RECURSIVE T001_TREE as ( select distinct T003_1, T003_3, (select T003_1 from t001 where T001.T001_1 = T1.T001_1b) as T003_1b FROM T001 T1 where T1.T003_1 = 'aFcGzkMlus4YOBbB7w9WP2' union all --Предыдущие документы select D.T003_1, D.T003_3, (select T003_1 from t001 where T001.T001_1 = D.T001_1b) as T003_1b FROM T001 D, T001_TREE Db where D.T003_3 >= '15.12.2008' and D.T003_1 = Db.T003_1b union all --Поддокументы "например акты производства" select D.T003_1, D.T003_3, (select T003_1 from t001 where T001.T001_1 = D.T001_1b) as T003_1b FROM T003 T3 join T001_TREE Db on T3.T003_1b = Db.T003_1 and T3.IDDoc <> 53 join T001 D on D.T003_1 = T3.T003_1 ) select * from T001_TREE но тут есть один нюанс под документы ломают всю нормальную логику дерева т.к. у них свои даты и они имеют права списывать товар в разные периоды. По сути в этом запросе мы ищем были ли ссылки на документ котором мы хотим сослаться на торар из документа начиная с '15.12.2008' из документов отписанных ранее. Я сейчас решил эту задачу так HList = b_StrListCreate(0, 1); if (exists( WITH RECURSIVE T001_TREE as ( select distinct T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = T1.T001_1b)) as T003_1b FROM T001 T1 where T1.T003_1 = :VT003_1--T001.T001_1 =NEW.T001_1b union all --Предыдущие документы select D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM T001 D join T001_TREE Db on D.T003_1 = Db.T003_1b where D.T003_3 >= :VT003_3 union all --Поддокументы "например акты производства" select D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM T003 T3 join T001_TREE Db on T3.T003_1b = Db.T003_1 and T3.IDDoc <> 53 join T001 D on D.T003_1 = T3.T003_1 ) select * from T001_TREE where T003_1 = new.T003_1 ))then begin b_StrListDestroy(HList); EXECUTE PROCEDURE ERROR('', 'Рекурсия недопустима.'); end b_StrListDestroy(HList); вывод напрашивается сам можно было реализовать это простым добавлением возможности в WITH и написанное было бы такого вида в начале например (может и както по другому) WITH RECURSIVE T001_TREE as DISTINCT T003_1b ( И еще есть момент почему запрещено писать так WITH RECURSIVE T001_TREE as ( select distinct T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = T1.T001_1b)) as T003_1b FROM T001 T1 where T1.T003_1 = :VT003_1--T001.T001_1 =NEW.T001_1b union all --Предыдущие документы select distinct D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM T001 D join T001_TREE Db on D.T003_1 = Db.T003_1b where D.T003_3 >= :VT003_3 union all --Поддокументы "например акты производства" select distinct D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM T003 T3 join T001_TREE Db on T3.T003_1b = Db.T003_1 and T3.IDDoc <> 53 join T001 D on D.T003_1 = T3.T003_1 ) select * from T001_TREE where T003_1 = new.T003_1 то есть distinct в каждом сиквеле суть заключается в следующем 1 сиквел делает выборку 1 строка из за distinct вместо 276!!!!!!!!!!! 2 сиквел возвращает кучу одинаковых значений получаем кучу лишних чтений 3 тоже что и в 2 Почему я чситаю что distinct должен работать в других частях смотрим вот это --Предыдущие документы select distinct D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM T001 D join T001_TREE Db on D.T003_1 = Db.T003_1b where D.T003_3 >= :VT003_3 это по сути есть при выполнении запроса T001_TREE(X) begin --Предыдущие документы select distinct D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM T001 D where D.T003_3 >= :VT003_3 and D.T003_1 = :X end штуку написали классную но добавив в нее еще 2 функционала и мама дорогая как круто все будет.