Postgres 中数组列的内部连接

s.m*_*.m. 7 postgresql join array catalogs

在 Postgres 9.4 中,我试图提取UNIQUEPostgres 中给定表的约束中涉及的所有列的名称。

看起来此类列的名称包含在pg_constraint. 根据文档,与我的问题相关的列称为conkey,它恰好是一个ints数组。

关键是,我提出的查询给了我错误的结果,我很确定这是因为我conkey以错误的方式加入。查询如下:

SELECT
    pg_attribute.attname,
    pg_constraint.*
FROM
    pg_attribute
INNER JOIN pg_constraint 
        ON pg_attribute.attnum = ANY (pg_constraint.conkey)
WHERE pg_constraint.conrelid = (
    SELECT
        oid
    FROM
        pg_class
    WHERE
        relname LIKE 'test_table'
)
AND pg_constraint.contype = 'u'; -- to filter out non-unique constraints
Run Code Online (Sandbox Code Playgroud)

这是一个用于快速重现的表 DDL:

CREATE TABLE "test_table" (
"date" date DEFAULT now() NOT NULL,
"foo" varchar COLLATE "default" NOT NULL
CONSTRAINT "test_table_foo_key" UNIQUE ("foo")
)
WITH (OIDS=FALSE);

ALTER TABLE "test_table" OWNER TO "postgres";
Run Code Online (Sandbox Code Playgroud)

现在,谁能告诉我我做错了什么?有没有更简单的方法来完全获取我想要的信息?

我正在尝试检索受约束表的名称,因为我正在编写的应用程序需要解决当前UPSERTPostgres 中的缺失问题。这个想法是使用 CTE 进行插入或更新,但由于我事先不知道受约束的列是什么,因此我需要进行一些内省。

dez*_*zso 7

你错过了两个表之间的连接。该...relid列必须匹配,太:

SELECT attname, c.* 
  FROM pg_attribute a 
  JOIN pg_constraint c 
    ON attrelid = conrelid -- this was missing
   AND attnum = ANY (conkey) 
 WHERE attrelid = 'test_table'::regclass;
Run Code Online (Sandbox Code Playgroud)

  • `WHERE attrelid = 'test_table'::regclass` 可以,因为 `regclass` 已经*是*一个 `oid` 别名。[一个特别的。](http://www.postgresql.org/docs/current/interactive/datatype-oid.html) (2认同)