2009-07-31 19 views

Respuesta

17

La consulta anterior es muy malo, ya que es muy lento.

recomendaría este versión oficial:

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

si se necesita esquema de la consulta es el siguiente

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

Estoy bastante seguro de que no necesita unirse con pg_namespace. El oid de pg_class es único así que cuando lo lances a un regllass ya estás implicando el nombre del esquema. Si necesita el nombre del esquema, simplemente inclúyalo en el nombre de la tabla: 'public.foo' :: regclass. –

+1

"La consulta anterior es muy mala, ya que es muy lenta". Evite hacer referencia a la posición relativa en la página de otras respuestas, ya que esto cambia con el tiempo y según el método de clasificación seleccionado. En cambio, la forma más segura de referirse al futuro a otra respuesta es vincularla. – faintsignal

5

Eche un vistazo a la tabla del sistema pg_constraint. O information_schema.table_constraints ver si prefiere mantenerse cerca del estándar SQL.

Para un ejemplo completo, conéctese a un DB usando psql con la opción "-E" y escriba \d <some_table> - verá las consultas reales utilizadas para describir una tabla.

+0

Además, combine esto con los datos de pg_indexes, y usted debe ser bastante bueno. Realmente, una clave principal es solo un índice único con nulo en todos los campos. –

15

Para proporcionar un poco recta de SQL, se puede enumerar las columnas de clave principal y sus tipos 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

Cuando ejecuto esto en mi servidor postgres, obtengo un conjunto de resultados vacío. Antes de que preguntes, reemplacé '' mytable'' con el nombre correcto de la tabla. ¿Debo estar en un contexto o alcance específico para que esto funcione? – 2mac

1

Cuidado con los índices en el que el orden de las columnas se diferencia del orden de las columnas de la tabla. (es decir, si la clave principal usó las columnas 3, 2 y 1)

La siguiente consulta es mucho más compleja, pero devuelve las columnas en el orden correcto. (Eliminar la cláusula 'indisprimary' para obtener la misma información para todos los índices en una tabla)

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

preservar el orden de columna utilizando 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

Los SQL declaraciones siguientes funciona para mí:

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; 

Se toma directamente de here.

Cuestiones relacionadas