Gau*_*nia 53 sql database postgresql foreign-keys
我正在使用PostgreSQL,我试图将表中具有特定列的所有表列为外键/引用.可以这样做吗?我确定这些信息存储在某个地方,information_schema
但我不知道如何开始查询它.
Ric*_*iwi 66
select R.TABLE_NAME
from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE u
inner join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS FK
on U.CONSTRAINT_CATALOG = FK.UNIQUE_CONSTRAINT_CATALOG
and U.CONSTRAINT_SCHEMA = FK.UNIQUE_CONSTRAINT_SCHEMA
and U.CONSTRAINT_NAME = FK.UNIQUE_CONSTRAINT_NAME
inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE R
ON R.CONSTRAINT_CATALOG = FK.CONSTRAINT_CATALOG
AND R.CONSTRAINT_SCHEMA = FK.CONSTRAINT_SCHEMA
AND R.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
WHERE U.COLUMN_NAME = 'a'
AND U.TABLE_CATALOG = 'b'
AND U.TABLE_SCHEMA = 'c'
AND U.TABLE_NAME = 'd'
Run Code Online (Sandbox Code Playgroud)
这使用完整的目录/模式/名称三元组来标识所有3个information_schema视图中的db表.您可以根据需要删除一个或两个.
该查询列出了对表'd'中的列'a'具有外键约束的所有表
Ton*_* K. 56
其他解决方案不保证在postgresql中工作,因为constraint_name不保证是唯一的; 因此你会得到误报.PostgreSQL用来命名约束愚蠢的东西,如'$ 1',如果你有一个旧的数据库,你一直在维护升级,你可能仍然有一些周围.
由于这个问题是针对AT PostgreSQL而你正在使用的,所以你可以查询内部postgres表pg_class和pg_attribute以获得更准确的结果.
注意:FK可以在多个列上,因此引用列(pg_attribute的attnum)是ARRAY,这是在答案中使用array_agg的原因.
您需要插入的唯一内容是TARGET_TABLE_NAME:
select
(select r.relname from pg_class r where r.oid = c.conrelid) as table,
(select array_agg(attname) from pg_attribute
where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as col,
(select r.relname from pg_class r where r.oid = c.confrelid) as ftable
from pg_constraint c
where c.confrelid = (select oid from pg_class where relname = 'TARGET_TABLE_NAME');
Run Code Online (Sandbox Code Playgroud)
如果你想以另一种方式(列出特定表所引用的所有内容),那么只需将最后一行更改为:
where c.conrelid = (select oid from pg_class where relname = 'TARGET_TABLE_NAME');
Run Code Online (Sandbox Code Playgroud)
哦,由于实际问题是针对特定列,您可以使用以下列指定列名:
select (select r.relname from pg_class r where r.oid = c.conrelid) as table,
(select array_agg(attname) from pg_attribute
where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as col,
(select r.relname from pg_class r where r.oid = c.confrelid) as ftable
from pg_constraint c
where c.confrelid = (select oid from pg_class where relname = 'TARGET_TABLE_NAME') and
c.confkey @> (select array_agg(attnum) from pg_attribute
where attname = 'TARGET_COLUMN_NAME' and attrelid = c.confrelid);
Run Code Online (Sandbox Code Playgroud)
就个人而言,我更喜欢基于引用的唯一约束而不是列进行查询.这看起来像这样:
SELECT rc.constraint_catalog,
rc.constraint_schema||'.'||tc.table_name AS table_name,
kcu.column_name,
match_option,
update_rule,
delete_rule
FROM information_schema.referential_constraints AS rc
JOIN information_schema.table_constraints AS tc USING(constraint_catalog,constraint_schema,constraint_name)
JOIN information_schema.key_column_usage AS kcu USING(constraint_catalog,constraint_schema,constraint_name)
WHERE unique_constraint_catalog='catalog'
AND unique_constraint_schema='schema'
AND unique_constraint_name='constraint name';
Run Code Online (Sandbox Code Playgroud)
这是一个允许按列名查询的版本:
SELECT rc.constraint_catalog,
rc.constraint_schema||'.'||tc.table_name AS table_name,
kcu.column_name,
match_option,
update_rule,
delete_rule
FROM information_schema.referential_constraints AS rc
JOIN information_schema.table_constraints AS tc USING(constraint_catalog,constraint_schema,constraint_name)
JOIN information_schema.key_column_usage AS kcu USING(constraint_catalog,constraint_schema,constraint_name)
JOIN information_schema.key_column_usage AS ccu ON(ccu.constraint_catalog=rc.unique_constraint_catalog AND ccu.constraint_schema=rc.unique_constraint_schema AND ccu.constraint_name=rc.unique_constraint_name)
WHERE ccu.table_catalog='catalog'
AND ccu.table_schema='schema'
AND ccu.table_name='name'
AND ccu.column_name='column';
Run Code Online (Sandbox Code Playgroud)
此查询仅需要引用的表名和列名,并生成包含外键两侧的结果集.
select confrelid::regclass, af.attname as fcol,
conrelid::regclass, a.attname as col
from pg_attribute af, pg_attribute a,
(select conrelid,confrelid,conkey[i] as conkey, confkey[i] as confkey
from (select conrelid,confrelid,conkey,confkey,
generate_series(1,array_upper(conkey,1)) as i
from pg_constraint where contype = 'f') ss) ss2
where af.attnum = confkey and af.attrelid = confrelid and
a.attnum = conkey and a.attrelid = conrelid
AND confrelid::regclass = 'my_table'::regclass AND af.attname = 'my_referenced_column';
Run Code Online (Sandbox Code Playgroud)
示例结果集:
confrelid | fcol | conrelid | col
----------+----------------------+---------------+-------------
my_table | my_referenced_column | some_relation | source_type
my_table | my_referenced_column | some_feature | source_type
Run Code Online (Sandbox Code Playgroud)
所有归功于Lane和Krogh在PostgreSQL论坛上.
小智 5
恢复外键名称以及表名称的简单请求:
SELECT CONSTRAINT_NAME, table_name
FROM
information_schema.table_constraints
WHERE table_schema='public' and constraint_type='FOREIGN KEY'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
30180 次 |
最近记录: |