2009-07-31 7 views

Odpowiedz

17

Zapytanie powyżej jest bardzo zła, ponieważ jest bardzo powolny.

Polecam tę oficjalną wersję:

http://wiki.postgresql.org/wiki/Retrieve_primary_key_columns

jeśli jest potrzebny schemat kwerenda jest następujący

SELECT    
    pg_attribute.attname, 
    format_type(pg_attribute.atttypid, pg_attribute.atttypmod) 
FROM pg_index, pg_class, pg_attribute, pg_namespace 
WHERE 
    pg_class.oid = 'foo'::regclass AND 
    indrelid = pg_class.oid AND 
    nspname = 'public' AND 
    pg_class.relnamespace = pg_namespace.oid AND 
    pg_attribute.attrelid = pg_class.oid AND 
    pg_attribute.attnum = any(pg_index.indkey) 
AND indisprimary 
+0

Jestem prawie pewien, że nie musisz dołączać do pg_namespace. Oid klasy pg_class jest unikatowy, więc kiedy rzucisz go do reglasu, już sugerujesz nazwę schematu. Jeśli potrzebujesz nazwy schematu, po prostu umieść ją w nazwie tabeli: "public.foo" :: regclass. –

+1

"Powyższe zapytanie jest bardzo złe, ponieważ jest naprawdę powolne." Unikaj odwoływania się do względnej pozycji na stronie innych odpowiedzi, ponieważ zmienia się ona wraz z upływem czasu i wybraną metodą sortowania. Zamiast tego najbardziej przyszłościowym sposobem odniesienia się do innej odpowiedzi jest link do niej. – faintsignal

5

Spójrz na tabelę systemową pg_constraint. Lub information_schema.table_constraints, jeśli wolisz trzymać się blisko standardu SQL.

Aby uzyskać pełny przykład, połącz się z bazą danych za pomocą psql za pomocą opcji "-E" i wpisz \d <some_table> - zobaczysz rzeczywiste zapytania używane do opisu tabeli.

+0

Dodatkowo połącz to z danymi z pg_indexes, a powinieneś być całkiem niezły. Naprawdę klucz podstawowy jest po prostu unikatowym indeksem z niezerową wartością we wszystkich polach. –

15

Aby zapewnić prostą nieco SQL, można wymienić kolumny klucza podstawowego i ich typy z:

SELECT 
c.column_name, c.data_type 
FROM 
information_schema.table_constraints tc 
JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name) 
JOIN information_schema.columns AS c ON c.table_schema = tc.constraint_schema AND tc.table_name = c.table_name AND ccu.column_name = c.column_name 
where constraint_type = 'PRIMARY KEY' and tc.table_name = 'mytable'; 
+2

Po uruchomieniu tego na moim serwerze Postgres otrzymuję pusty zestaw wyników. Zanim zapytasz, zastąpiłem ''mytable'' poprawną nazwą tabeli. Czy muszę działać w określonym kontekście lub zakresie? – 2mac

1

Strzeż indeksów, gdzie kolejność kolumn różni się od celu kolumnie tabeli. (tj. jeśli klucz podstawowy użył kolumn 3, 2 i 1)

Poniższe zapytanie jest znacznie bardziej złożone, ale zwraca kolumny w odpowiedniej kolejności. (Usunąć 'indisprimary klauzulę aby uzyskać te same informacje dla wszystkich indeksów na stole)

WITH ndx_list AS 
(
    SELECT pg_index.indexrelid 
     FROM pg_index, pg_class 
    WHERE pg_class.relname = 'test_indices_table' 
     AND pg_class.oid = pg_index.indrelid 
     AND pg_index.indisprimary 
), ndx_cols AS 
(
    SELECT pg_class.relname AS index_name, UNNEST(i.indkey) AS col_ndx, i.indisunique, i.indisprimary 
    FROM pg_class, pg_index i 
    WHERE pg_class.oid = i.indexrelid 
     AND pg_class.oid IN (SELECT indexrelid FROM ndx_list) 
) 
    SELECT ndx_cols.index_name, ndx_cols.indisunique, ndx_cols.indisprimary, 
     a.attname, format_type(a.atttypid, a.atttypmod), a.attnum 
    FROM pg_class c, pg_attribute a 
    JOIN ndx_cols ON (a.attnum = ndx_cols.col_ndx) 
    WHERE c.oid = 'test_indices_table'::regclass 
    AND a.attrelid = c.oid 
0

Zachowując kolejność kolumn przy użyciu generate_subscripts:

SELECT 
    a.attname, 
    format_type(a.atttypid, a.atttypmod) 
FROM 
    pg_attribute a 
    JOIN (SELECT *, GENERATE_SUBSCRIPTS(indkey, 1) AS indkey_subscript FROM pg_index) AS i 
    ON 
     i.indisprimary 
     AND i.indrelid = a.attrelid 
     AND a.attnum = i.indkey[i.indkey_subscript] 
WHERE 
    a.attrelid = 'your_table'::regclass 
ORDER BY 
    i.indkey_subscript 
3

Poniższe SQL sprawozdania pracuje dla mnie:

SELECT a.attname 
FROM pg_index i 
JOIN pg_attribute a ON a.attrelid = i.indrelid 
        AND a.attnum = ANY(i.indkey) 
WHERE i.indrelid = 'tablename'::regclass 
AND i.indisprimary; 

Jest on pobierany bezpośrednio z here.

Powiązane problemy