2009-07-31 13 views

risposta

17

La query sopra è molto male come è molto lento.

consiglio questo versione ufficiale:

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

se è necessario lo schema della query è la seguente

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

Sono abbastanza sicuro che non è necessario unirsi a pg_namespace. L'oid di pg_class è univoco, quindi quando lo lanci su una regclass stai già implicando il nome dello schema. Se hai bisogno del nome dello schema, includilo nel nome della tabella: 'public.foo' :: regclass. –

+1

"La query sopra è pessima in quanto è molto lenta." Si prega di evitare di fare riferimento alla posizione relativa sulla pagina di altre risposte in quanto questo cambia nel tempo e dal metodo di ordinamento selezionato. Invece il modo più a prova di futuro di riferirsi a un'altra risposta è collegarlo ad esso. – faintsignal

5

Dai un'occhiata alla tabella di sistema pg_constraint. O vista information_schema.table_constraints se si preferisce rimanere vicini allo standard SQL.

Per un esempio completo, connettersi a un DB utilizzando psql con l'opzione "-E" e digitare \d <some_table> - verranno visualizzate le query effettive utilizzate nella descrizione di una tabella.

+0

Inoltre, combina questo con i dati di pg_indexes e dovresti essere abbastanza buono. In realtà una chiave primaria è solo un indice univoco con non null su tutti i campi. –

15

Per fornire un po 'dritto di SQL, è possibile elencare le colonne chiave primaria e le loro tipologie con:

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

Quando lo eseguo sul mio server Postgres, ottengo un set di risultati vuoto. Prima di chiedere, ho sostituito ''mytable'' con il nome corretto del tavolo. Devo essere in uno specifico contesto o ambito per far funzionare tutto questo? – 2mac

1

Beware of indici in cui l'ordine delle colonne è diverso da ordine delle colonne della tabella. (Ad esempio, se la chiave primaria utilizzava le colonne 3, 2 e 1)

La seguente query è molto più complessa, ma restituisce le colonne nell'ordine corretto. (Rimuovere la clausola 'indisprimary' per ottenere le stesse informazioni per tutti gli indici su un tavolo)

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

Preservare l'ordine delle colonne utilizzando 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

Le seguenti SQL dichiarazioni funziona per me:

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; 

Viene preso direttamente da here.

Problemi correlati