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/Компиляция_платформы_Гедымин
Отправить комментарий