2009-10-14 3 views
1

postgres 8.3 데이터베이스를 검사하여 외래 키의 세부 정보를 검색하려고합니다.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} 

을 준 거의 다 왔어. 그러나 열 번호를 열 이름으로 변환하려는 노력으로 아직 원하는 결과를 얻지 못했습니다. 인터넷 검색은 저에게 다시 을주었습니다.

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"; 

는 그의 대답에 주석의 표준이 아닌 방법을 용서하게 얻을 수있는 전체 쿼리를 정의 할 수 있습니다 난 아직도 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을 찾으십시오). 분명히이 쿼리를 큰 쿼리에 병합 할 수 있지만 이는 일반적인 아이디어를 제공합니다.