【发布时间】:2019-12-04 19:19:44
【问题描述】:
有没有办法列出 SQLite 数据库中的所有外键?
它们似乎没有存储在 sqlite_master 中,PRAGMA foreign_key_list('table') 一次只列出一个。
或者,有没有办法列出哪些外键引用了一个表?
【问题讨论】:
标签: sqlite
有没有办法列出 SQLite 数据库中的所有外键?
它们似乎没有存储在 sqlite_master 中,PRAGMA foreign_key_list('table') 一次只列出一个。
或者,有没有办法列出哪些外键引用了一个表?
【问题讨论】:
标签: sqlite
似乎所有(或许多)PRAGMA 命令都可以通过一个小技巧以编程方式选择;
通常被称为:
PRAGMA table_info('my_table');
PRAGMA foreign_key_list('my_table');
但这也可以做到:
SELECT * FROM pragma_table_info('my_table');
SELECT * FROM pragma_foreign_key_list('my_table');
而且schema也可以(或多或少)获得:
.schema pragma_table_info
/* pragma_table_info(cid,name,type,"notnull",dflt_value,pk) */;
.schema pragma_foreign_key_list
/* pragma_foreign_key_list(id,seq,"table","from","to",on_update,on_delete,"match") */
所以,让所有 fks 在sqlite_master 和 pragma_foreign_key_list 之间加入一个 JOIN 就可以了:
SELECT
m.name
, p.*
FROM
sqlite_master m
JOIN pragma_foreign_key_list(m.name) p ON m.name != p."table"
WHERE m.type = 'table'
ORDER BY m.name
;
请注意,pragma_foreign_key_list 的某些字段,例如 table、from、...必须被引用;
【讨论】:
ON m.name != p."table",因为 SQLite 允许 (INNER) JOIN 而不打开? (将其视为 ON 1=1,就像在 CROSS JOIN 中一样。)
ON。根据个人喜好,我更喜欢输入更多字符并明确说明正在发生的事情。
使用 SQLite shell,使用 .schema 指令,并使用 GREP 过滤包含 REFERENCES 的行。
来自SQLite仓库中的shell.c,主干今天的版本,两个查询:
SELECT sql
FROM (
SELECT sql sql, type type, tbl_name tbl_name, name name
FROM sqlite_master
UNION ALL
SELECT sql, type, tbl_name, name
FROM sqlite_temp_master
)
WHERE tbl_name LIKE shellstatic()
AND type != 'meta'
AND sql NOTNULL
ORDER BY substr(type, 2, 1), name
和
SELECT sql
FROM (
SELECT sql sql, type type, tbl_name tbl_name, name name
FROM sqlite_master
UNION ALL
SELECT sql, type, tbl_name, name
FROM sqlite_temp_master
)
WHERE type != 'meta'
AND sql NOTNULL
AND name NOT LIKE 'sqlite_%'
ORDER BY substr(type, 2, 1), name
第二个可能就是你要找的。p>
【讨论】:
sqlite_master 获取表名,然后为每个表调用PRAGMA foreign_keys)是最简单的方式。不幸的是,PRAGMA 结果不能与 SELECT 语句结合......
PRAGMA foreign_key_list,而不是PRAGMA foreign_keys。