gpt4 book ai didi

php - PostgreSQL - 所有表的分层列表

转载 作者:行者123 更新时间:2023-11-29 12:10:20 25 4
gpt4 key购买 nike

我需要按层次顺序列出我的数据库 (PostgreSQL) 的所有表。这意味着:如果表“user”有表“role”的外键,那么它必须在列表中位于表“role”之后。

相当于:

EXEC sp_msdependencies @intrans = 1 

在 SQL Server 中。

我试过了,但没有成功:

SELECT
pt.table_name as tablename,
string_agg(DISTINCT ccu.table_name, ',') AS reftable
FROM information_schema.tables pt
LEFT JOIN information_schema.columns c
ON c.table_name = pt.table_name
LEFT JOIN information_schema.table_constraints tc
ON tc.table_name = pt.table_name AND tc.constraint_type = 'FOREIGN KEY'
LEFT JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name AND kcu.column_name = c.column_name
LEFT JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE pt.table_schema = 'public'
GROUP BY pt.table_name,pt.table_type
ORDER BY pt.table_type DESC, COUNT(TRUE) ASC;

最佳答案

我不认为你可以用一个简单的 SELECT 来做到这一点。您可能需要递归查询。

information_schema 似乎特别不适合这种情况,因为它假设约束名称在模式中是唯一的,而 Postgres 不强制执行。换句话说,如果您有两个同名的约束,我看不出有什么方法可以在 constraint_column_usage 中区分它们。所以你最好使用 Postgres 自己的目录。

这似乎有效,但我还没有彻底测试它:

WITH RECURSIVE ref (tbl, reftbl, depth) AS (
SELECT pg_class.oid, NULL::oid, 0
FROM pg_class
JOIN pg_namespace ON
pg_namespace.oid = pg_class.relnamespace
WHERE
relkind = 'r' AND
nspname = 'public' AND
NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE
conrelid = pg_class.oid AND
contype = 'f'
)
UNION ALL
SELECT conrelid, ref.tbl, ref.depth + 1
FROM ref
JOIN pg_constraint ON
confrelid = ref.tbl AND
contype = 'f'
)
SELECT
tbl::regclass::text as tablename,
string_agg(DISTINCT reftbl::regclass::text, ',') as reftables
FROM ref
GROUP BY tablename
ORDER BY max(depth)

关于php - PostgreSQL - 所有表的分层列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39426689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com