2009-10-14 3 views
1

Я пытаюсь заглянуть в базу данных postgres 8.3, чтобы получить информацию о ее внешних ключах . Представьте себе, у меня есть следующая схема:Introspect postgresql 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" 
); 

Тогда я хотел бы выполнить запрос, который producued следующее:

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} 

который почти есть. Но мои попытки конвертировать номера столбцов в столбцы имена еще не дали мне желаемого результата. Googling дал мне ниже, что снова, не совсем верно.

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 

Может ли кто-нибудь помочь мне сделать этот последний шаг?

ответ

3

Исправление ответа Питера Эйзентраута; для 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"; 

Простить нестандартный способ комментирования его ответа, я m все еще учится Как использовать 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 в документации). Очевидно, вы можете объединить этот запрос в свой большой запрос, но это должно дать вам общую идею.

 Смежные вопросы

  • Нет связанных вопросов^_^