Re: WITH RECURSIVE нуансы которые хотелось чтоб учли и добавили
"Boltik Evgeny" ... Еще обнаружил утечку в моем случае сервер в диспетчере задач как только открываю код с WITH. Сжерает несколько мегов. Проявляется на чистой базе из Эксперта. Могу выложить архив. Но размер его 85 мегов :(. Самому сегодня домой его пришлось тянуть с другого города. Если надо то выложу скажи почтовый я отправлю откуда забрать или пиша в асю 344208852 А то ты мой адрес не знаешь :) hvlad at users sourceforge net
Re: WITH RECURSIVE нуансы которые хотелось чтоб учли и добавили
"Vlad Khorsun" сообщил/сообщила в новостях следующее: news:gmcvih$av...@ger.gmane.org... "Boltik Evgeny" ... Вот сижу в догадках как и в первые разы. Баг иль не баг. По идее при DISTINCT должно быть меньше. Без примера данных я ничего не могу сказать Еще обнаружил утечку в моем случае сервер в диспетчере задач как только открываю код с WITH. Сжерает несколько мегов. Проявляется на чистой базе из Эксперта. Могу выложить архив. Но размер его 85 мегов :(. Самому сегодня домой его пришлось тянуть с другого города. Если надо то выложу скажи почтовый я отправлю откуда забрать или пиша в асю 344208852
Re: WITH RECURSIVE нуансы которые хотелось чтоб учли и добавили
"Boltik Evgeny" ... Вот сижу в догадках как и в первые разы. Баг иль не баг. По идее при DISTINCT должно быть меньше. Без примера данных я ничего не могу сказать -- Хорсун Влад
Re: WITH RECURSIVE нуансы которые хотелось чтоб учли и добавили
(SELECT DISTINCT S2.T003_1, (select F.T003_1 from t001 F where F.T001_1 = S2.T001_1b) as T003_1b, T3.T003_1b as T3_T003_1b FROM T003 T3 join T001 S2 on S2.T003_1 = T3.T003_1 where T3.IDDoc <> 53) D2 on D2.T3_T003_1b = Db.T003_1 ) весь результат 1991 строка но если внизу (SELECT /*DISTINCT */S2.T003_1 то почемуто всего 341 строка Вот сижу в догадках как и в первые разы. Баг иль не баг. По идее при DISTINCT должно быть меньше. А теперь еще прикол (SELECT DISTINCT S2.T003_1, (select F.T003_1 from t001 F where F.T001_1 = S2.T001_1b) as T003_1b, T3.T003_1b as T3_T003_1b FROM T003 T3 join T001 S2 on S2.T003_1 = T3.T003_1 where T3.IDDoc <> 53) D2 on D2.T3_T003_1b = Db.T003_1 ) select distinct T003_1 from T001_TREE получаем 274 записи (SELECT /*DISTINCT */S2.T003_1, (select F.T003_1 from t001 F where F.T001_1 = S2.T001_1b) as T003_1b, T3.T003_1b as T3_T003_1b FROM T003 T3 join T001 S2 on S2.T003_1 = T3.T003_1 where T3.IDDoc <> 53) D2 on D2.T3_T003_1b = Db.T003_1 ) select distinct T003_1 from T001_TREE получаем 74 записи Это как так?
Re: WITH RECURSIVE нуансы которые хотелось чтоб учли и добавили
Нихрена не понял, как обычно СП, что помогаешь горю. вывод напрашивается сам можно было реализовать это простым добавлением возможности в WITH и написанное было бы такого вида в начале например (может и както по другому) WITH RECURSIVE T001_TREE as DISTINCT T003_1b ( Что мешает делать выборку из T003_1b с 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 Стало select D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM (SELECT DISTINCT T003_1 FROM T001 where T003_3 >= :VT003_3) D join T001_TREE Db on D.T003_1 = Db.T003_1b За мысль огромное СП. Но я когда начинал так пробовал. Решил еще раз и снова возникли вопросы сделал так WITH RECURSIVE T001_TREE as ( select distinct T003_1, (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 D1.T003_1, D1.T003_1b FROM T001_TREE Db join (SELECT DISTINCT S1.T003_1, (select F.T003_1 from t001 F where F.T001_1 = S1.T001_1b) as T003_1b FROM T001 S1 where T003_3 >= '15.12.2008') D1 on D1.T003_1 = Db.T003_1b union all --Поддокументы "например акты производства" select D2.T003_1, D2.T003_1b FROM T001_TREE Db join (SELECT DISTINCT S2.T003_1, (select F.T003_1 from t001 F where F.T001_1 = S2.T001_1b) as T003_1b, T3.T003_1b as T3_T003_1b FROM T003 T3 join T001 S2 on S2.T003_1 = T3.T003_1 where T3.IDDoc <> 53) D2 on D2.T3_T003_1b = Db.T003_1 ) весь результат 1991 строка но если внизу (SELECT /*DISTINCT */S2.T003_1 то почемуто всего 341 строка Вот сижу в догадках как и в первые разы. Баг иль не баг. По идее при DISTINCT должно быть меньше.
Re: WITH RECURSIVE нуансы которые хотелось чтоб учли и добавили
Нихрена не понял, как обычно вывод напрашивается сам можно было реализовать это простым добавлением возможности в WITH и написанное было бы такого вида в начале например (может и както по другому) WITH RECURSIVE T001_TREE as DISTINCT T003_1b ( Что мешает делать выборку из T003_1b с 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 Стало select D.T003_1, b_StrListAddGet(:HList, (select T003_1 from t001 where T001.T001_1 = D.T001_1b)) as T003_1b FROM (SELECT DISTINCT T003_1 FROM T001 where T003_3 >= :VT003_3) D join T001_TREE Db on D.T003_1 = Db.T003_1b -- Хорсун Влад
WITH RECURSIVE нуансы которые хотелось чтоб учли и добавили
Привет всем. Начал юзать эту конструкцию. Перед началом были вопросы они решились. Но закралось смутное сомнение что будет ошибка. Поговорил с 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