WITH RECURSIVE ns_tree AS ( SELECT f.filename, CAST((f.xid || '_' || f.dbid) AS VARCHAR(1024)) AS path, l2.uses_xid, l2.uses_dbid FROM at_namespace_file f JOIN at_namespace_file_link l ON l.uses_xid = f.xid AND l.uses_dbid = f.dbid LEFT JOIN at_namespace_file_link l2 ON l2.filename = f.filename WHERE l.filename = :filename UNION ALL SELECT f.filename, (t.path || '-' || f.xid || '_' || f.dbid) AS path, l.uses_xid, l.uses_dbid FROM ns_tree t JOIN at_namespace_file f ON t.uses_xid = f.xid AND t.uses_dbid = f.dbid JOIN at_namespace_file_link l ON l.filename = f.filename WHERE POSITION ((f.xid || '_' || f.dbid) IN t.path) = 0) SELECT t.filename FROM ns_tree t UNION SELECT f.filename FROM ns_tree t JOIN at_namespace_file f ON f.xid = t.uses_xid AND f.dbid = t.uses_dbid LEFT JOIN at_namespace_file_link l ON l.filename = f.filename WHERE l.filename IS NULL
28 сент. 2013 г.
Неприятное ограничение рекурсивных CTE
Простейший способ заехать в дурдом -- это отладка рекурсивных запросов в уме. В предыдущем примере у нас закралась ошибка. Объекты, которые ни от кого не зависят, не попадут в итоговую выборку. Но, только в том случае, если глубина уровня их вложенности больше единицы. Всему виной JOIN at_namespace_file_link l ON l.filename = f.filename во второй части CTE. По логике вещей, тут должен быть LEFT JOIN, но рекурсивное CTE внутри себя не может участвовать во внешних объединениях. C'est la vie. И никакой возможности разрулить данную ситуацию внутри самого CTE не просматривается. Остается городить огород с объединением двух выборок.
2 комментария:
А Можно узнать В какой версии Делфи разрабатываетса Данный продукт.
Delphi 5.
Все исходники в googlecode и доступны
через SVN. Единственное исключение --
FastReport 4. Его исходники надо купить
отдельно:
http://www.fast-report.com/en/
FastReport подключается через
условную компиляцию. Так что,
если его исходников не будет, то
проект все равно откомпилируется.
Инструкция по компиляции тут:
http://gsbelarus.com/gs/wiki/index.php/Компиляция_платформы_Гедымин
Отправить комментарий