postgresql Postgres使用表架构获取外键

ikfrs5lh  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(201)

我是新来的postgres。我找到了一个几乎可以满足我需要的SQL,但我还没有弄清楚如何将表所有者作为结果集的一部分,以及如何在where子句中使用表所有者。我把注解放在我需要的列引用的地方。下面是我的代码:

SELECT (select  r.relname from pg_class r where r.oid = c.confrelid) as base_table,
       a.attname as base_col,
       --base table schema
       (select r.relname from pg_class r where r.oid = c.conrelid) as referencing_table,
       UNNEST((select array_agg(attname) from pg_attribute where attrelid = c.conrelid and array[attnum] <@ c.conkey)) as referencing_col
       -- referenceing table schema       
  FROM pg_constraint c join pg_attribute a on c.confrelid=a.attrelid and a.attnum = ANY(confkey)
 WHERE c.confrelid = (select oid from pg_class where relname = 'table_name')
    -- and table_schema = 'schema_name'
   AND c.confrelid!=c.conrelid;

任何帮助将不胜感激。

yvfmudvl

yvfmudvl1#

您的查询不合理,在复合外键的情况下,它返回了太多(重复)的行。我建议在这些情况下使用string_agg()返回列名列表。将pg_class连接到pg_constraint以获取表的所有者名称:

select
    cb.relname as base_table,
    cb.relowner::regrole as base_owner,
    (select string_agg(attname, ',') 
        from pg_attribute 
        where attrelid = confrelid and attnum = any(confkey)
    ) as base_columns,
    cr.relname as referencing_table,
    cr.relowner::regrole as reftable_owner,
    (select string_agg(attname, ',') 
        from pg_attribute 
        where attrelid = conrelid and attnum = any(conkey)
    ) as ref_columns
from pg_constraint c 
join pg_class cb on cb.oid = c.confrelid
join pg_class cr on cr.oid = c.conrelid
where c.confrelid = 'public.master'::regclass
-- sample owner condition
and cb.relowner = 'postgres'::regrole

db<>fiddle.中测试
更新。系统编录pg_class的列relnamespace包含有关表模式的信息:

select
    cb.relname as base_table,
    cb.relnamespace::regnamespace as base_schema,
    (select string_agg(attname, ',') 
        from pg_attribute 
        where attrelid = confrelid and attnum = any(confkey)
    ) as base_columns,
    cr.relname as referencing_table,
    cr.relnamespace::regnamespace as reftable_schema,
    (select string_agg(attname, ',') 
        from pg_attribute 
        where attrelid = conrelid and attnum = any(conkey)
    ) as ref_columns
from pg_constraint c 
join pg_class cb on cb.oid = c.confrelid
join pg_class cr on cr.oid = c.conrelid
-- sample schema condition
where cb.relnamespace = 'public'::regnamespace;

db<>fiddle.中测试

相关问题