【问题标题】:Introspect postgresql 8.3 to find foreign keys内省 postgresql 8.3 以查找外键
【发布时间】:2009-10-14 15:23:18
【问题描述】:

我正在尝试自省 postgres 8.3 数据库以检索其详细信息 外键。想象一下,我有以下架构:

CREATE TABLE "a" (
 "id" SERIAL PRIMARY KEY
);

CREATE TABLE "b" (
 "one" integer,
 "two" integer,
 "a_id" integer REFERENCES "a",
 PRIMARY KEY ("one", "two")
);

CREATE TABLE "c" (
 "id" SERIAL PRIMARY KEY,
 "a_id" integer REFERENCES "a",
 "b_one" integer,
 "b_two" integer,
 FOREIGN KEY ("b_one", "b_two") REFERENCES "b"
);

然后我想运行一个产生以下内容的查询:

table | columns        | foreign table | foreign columns
--------------------------------------------------------
 b    | {a_id}         | a             | {id}
 c    | {a_id}         | a             | {id}
 c    | {b_one, b_two} | b             | {one, two}

我的第一次努力给了我查询

SELECT conrelid::regclass as "table",
       conkey as columns, 
       confrelid::regclass as "foreign table", 
       confkey as "foreign columns"
  FROM pg_constraint
 WHERE contype = 'f' ;

 table | columns | foreign table | foreign columns 
-------+---------+---------------+-----------------
 b     | {3}     | a             | {1}
 c     | {2}     | a             | {1}
 c     | {3,4}   | b             | {1,2}

几乎就在那里。但我努力将列号转换为列 名称尚未为我提供预期的结果。谷歌搜索给了我 下面这又是,不太对。

SELECT conrelid::regclass as "table",
       a.attname as columns,
       confrelid::regclass as "foreign table",
       af.attname as "foreign columns"
  FROM pg_attribute AS af,
       pg_attribute AS 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'
         ) AS ss
       ) AS ss2
 WHERE af.attnum = confkey
   AND af.attrelid = confrelid
   AND a.attnum = conkey
   AND a.attrelid = conrelid ;

 table | columns | foreign table | foreign columns 
-------+---------+---------------+-----------------
 b     | a_id    | a             | id
 c     | a_id    | a             | id
 c     | b_one   | b             | one
 c     | b_two   | b             | two

谁能帮我迈出最后一步?

【问题讨论】:

    标签: sql postgresql foreign-keys introspection


    【解决方案1】:

    充实 Peter Eisentraut 的答案;对于 postgresql 8.3,array_agg 函数可以定义为

    CREATE AGGREGATE array_accum (anyelement)
    (
        sfunc = array_append,
        stype = anyarray,
        initcond = '{}'
    );
    

    然后得到我想要的答案的完整查询就变成了

    SELECT "table",
           array_accum(columns) AS columns,
           "foreign table",
           array_accum("foreign columns") AS "foreign columns"
      FROM ( SELECT conrelid::regclass AS "table",
                    a.attname as columns,
                    confrelid::regclass as "foreign table",
                    af.attname as "foreign columns"
               FROM pg_attribute AS af,
                    pg_attribute AS 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'
                      ) AS ss
                    ) AS ss2
              WHERE af.attnum = confkey
                AND af.attrelid = confrelid
                AND a.attnum = conkey
                AND a.attrelid = conrelid
           ) AS ss3
      GROUP BY "table",
               "foreign table";
    

    请原谅评论他的答案的非标准方式,我还在学习 如何使用 Stackoverflow,并且一开始没有创建帐户 实例没有帮助。

    【讨论】:

      【解决方案2】:
      SELECT table, array_agg(columns), foreign_table, array_agg(foreign_columns) FROM (your query here) GROUP BY table, foreign_table;
      

      array_agg 需要 PostgreSQL 8.4。对于早期版本,您可以定义自己的(在文档中查找 array_accum)。显然,您可以将此查询合并到您的大查询中,但这应该会给您一个大致的思路。

      【讨论】:

        猜你喜欢
        • 2011-12-07
        • 1970-01-01
        • 1970-01-01
        • 2016-11-01
        • 2011-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多