PostgreSQL 获取带有表模式的外键

huangapple go评论66阅读模式
英文:

Postgres get foreign key with table schema

问题

以下是您提供的内容的中文翻译部分:

"我是新手使用PostgreSQL。我找到了一段SQL代码,几乎满足我的需求,但我还没有搞清楚如何将表所有者作为结果集的一部分以及如何在WHERE子句中使用表所有者。我在需要列引用的地方添加了注释。以下是我的代码:

SELECT (select r.relname from pg_class r where r.oid = c.confrelid) as base_table,
       a.attname as base_col,
	   --基础表架构
       (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
	   -- 引用表架构
  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')
	-- 和表架构 = 'schema_name'
   AND c.confrelid!=c.conrelid;

感谢任何帮助。"

英文:

I am new to postgres. I found a SQL that does almost what I need, but I have not figure out how to get the table owner as part of the result set and how to use the table owner in the where clause. I put comments where I would like the column references I need. Here is my code below:

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;

Any help would be appreciated.

答案1

得分: 2

以下是您要翻译的内容:

你的查询不够准确,在复合外键的情况下返回了太多(重复的)行。我建议在这些情况下返回列名的列表,使用 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
-- 示例所有者条件
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
-- 示例模式条件
where cb.relnamespace = 'public'::regnamespace;

db<>fiddle 中进行测试。

英文:

Your query is not sound, it returns too many (duplicated) rows in the case of composite foreign keys. I would suggest returning lists of column names in these cases, using string_agg(). Join pg_class to pg_constraint to get owner names of the tables:

select
	cb.relname as base_table,
	cb.relowner::regrole as base_owner,
	(select string_agg(attname, &#39;,&#39;) 
		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, &#39;,&#39;) 
		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 = &#39;public.master&#39;::regclass
-- sample owner condition
and cb.relowner = &#39;postgres&#39;::regrole

Test it in db<>fiddle.

Update. The column relnamespace of the system catalog pg_class contains information about a table schema:

select
    cb.relname as base_table,
    cb.relnamespace::regnamespace as base_schema,
    (select string_agg(attname, &#39;,&#39;) 
        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, &#39;,&#39;) 
        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 = &#39;public&#39;::regnamespace;

Test it in db<>fiddle.

huangapple
  • 本文由 发表于 2023年6月12日 03:27:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定