使用编译指示foreign_key_list的sqlite递归公用表表达式

问题描述 投票:0回答:2

我正在尝试枚举给定表的所有父表及其父表。

以下 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; 
sql sqlite recursive-query
2个回答
0
投票
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。


0
投票
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;
© www.soinside.com 2019 - 2024. All rights reserved.