我正在尝试枚举给定表的所有父表及其父表。
以下 sqlite 脚本设置父级>子级>孙级层次结构,确实为每个表选择 pragma_foreign_key_list,但我无法让 cte 工作。
如果可以的话,我该怎么做?
PRAGMA foreign_keys = on;
create table parent(
id INTEGER PRIMARY KEY
);
create table child
(
id INTEGER PRIMARY KEY,
parentId REFERENCES parent(id)
);
create table grandChild
(
id INTEGER PRIMARY KEY,
childId REFERENCES child(id)
);
.mode column
.header on
select 'parent' as childTable, "from" as childField, "table" as parentTable, "to" as parentField
from pragma_foreign_key_list('parent');
select 'child' as childTable, "from" as childField, "table" as parentTable, "to" as parentField
from pragma_foreign_key_list('child');
select '' as "";
select 'grandChild' as childTable, "from" as childField, "table" as parentTable, "to" as parentField
from pragma_foreign_key_list('grandChild');
select '' as "";
select distinct "table" as tName from pragma_foreign_key_list('grandChild');
select '' as "";
with recursive tabs as (
select distinct "table" as tName from pragma_foreign_key_list('grandChild')
union all
select distinct "table" from pragma_foreign_key_list(quote(select tName from tabs))
)
select * from tabs;
with recursive tabs(tab) as (
select distinct "table" as tab
from pragma_foreign_key_list('grandChild')
union all
select distinct name as tab
from sqlite_master m, tabs t
where exists (
select * from pragma_foreign_key_list(t.tab) where "table" = m.Name)
)
select * from tabs;
正如我在评论中提到的 - 我们无法从 select 中从 pragma_foreign_key_list 中进行选择。 pragma_foreign_key_list 上的 OUTER APPLY 会很有帮助,但 SQLite 不支持它。因此,我尝试根据我们的递归选项卡,使用 EXISTS 过滤器从所有表中进行选择来更改 OUTER APPLY。
WITH RECURSIVE CTE AS (
SELECT 'grandChild' AS `table`
UNION ALL
SELECT fk.`table`
FROM CTE c, pragma_foreign_key_list(c.`table`) fk
)
SELECT *
FROM CTE;
或
WITH RECURSIVE CTE AS (
SELECT 'grandChild' AS `table`, 'grandChild' AS path
UNION ALL
SELECT fk.`table`, path || ' -> ' || fk.`table` AS path
FROM CTE c, pragma_foreign_key_list(c.`table`) fk
)
SELECT *
FROM CTE;