SQL列出引用表中特定列的所有表
我正在使用PostgreSQL,我试图列出所有表中有一个特定的列从一个表作为外键/引用。 可以这样做吗? 我确信这些信息存储在information_schema
某处,但我不知道如何开始查询。
谢谢!
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'
这将使用完整的目录/模式/名称三元组来标识所有3个information_schema视图中的数据库表。 您可以根据需要放置一两个。
查询列出了所有对表'd'中的列'a'具有外键约束的表
其他解决scheme不保证在postgresql中工作 ,因为constraint_name不保证是唯一的; 因此你会得到误报。 PostgreSQL用来命名“$ 1”这样愚蠢的东西,如果你有一个老的数据库,你通过升级来维护,那么你可能还会有其他一些。
由于这个问题的目标是在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');
如果你想以另一种方式(列出特定表格引用的所有内容),则只需将最后一行更改为:
where c.conrelid = (select oid from pg_class where relname = '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') and c.confkey @> (select array_agg(attnum) from pg_attribute where attname = 'TARGET_COLUMN_NAME' and attrelid = c.confrelid);
就个人而言,我更喜欢根据引用的唯一约束而不是列进行查询。 这看起来像这样:
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';
这是一个允许按列名查询的版本:
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';
此查询只需要引用的表名和列名称 ,并生成一个包含外键两侧的结果集。
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';
示例结果集:
confrelid | fcol | conrelid | col ----------+----------------------+---------------+------------- my_table | my_referenced_column | some_relation | source_type my_table | my_referenced_column | some_feature | source_type
所有功劳在PostgreSQL论坛里的Lane和Krogh 。
一个简单的请求恢复外键的名字以及表的名字:
SELECT CONSTRAINT_NAME,table_name FROM information_schema.table_constraints WHERE table_schema ='public'and constraint_type ='FOREIGN KEY'
SELECT main_table.table_name AS main_table_table_name, main_table.column_name AS main_table_column_name, main_table.constraint_name AS main_table_constraint_name, info_other_table.table_name AS info_other_table_table_name, info_other_table.constraint_name AS info_other_table_constraint_name, info_other_table.column_name AS info_other_table_column_name FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE main_table INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS other_table ON other_table.unique_constraint_name = main_table.constraint_name INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE info_other_table ON info_other_table.constraint_name = other_table.constraint_name WHERE main_table.table_name = 'MAIN_TABLE_NAME';