Primärschlüssel für alle Tabellen auflisten - Postgresql


14

Gibt es eine Abfrage, die das erledigt?

Ich habe einige Abfragen gefunden, die dies für eine Tabelle ermöglichen, konnte sie jedoch nicht ändern, damit ich Folgendes sehen kann:

tablename | column | type

1
Wenn ich dies fragen würde, würde ich gerne die Ordnungsposition einer Spalte in der PK wissen (einige PKs haben mehr als 1 Spalten und die Reihenfolge kann von Bedeutung sein).
ypercubeᵀᴹ

Antworten:


13

Etwas wie das:

select tc.table_schema, tc.table_name, kc.column_name
from information_schema.table_constraints tc
  join information_schema.key_column_usage kc 
    on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema and kc.constraint_name = tc.constraint_name
where tc.constraint_type = 'PRIMARY KEY'
  and kc.ordinal_position is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;

Diese Abfrage zeigt nicht nur Primärschlüssel, sondern auch eindeutige Indizes
Michał Niklas

@ MichałNiklas geht es nicht.
Dezso

1
@DarielPratama: Die Bedingung tc.constraint_type = 'PRIMARY KEY'zeigt nur Primärschlüssel an. Jeder Primärschlüssel wird jedoch durch einen eindeutigen Index gesichert
a_horse_with_no_name

2
@a_horse_with_no_name Ich glaube, das ist falsch. position_in_unique_constraintGibt die Position für den AUSLÄNDISCHEN Schlüssel an. Für Primärschlüssel ist sie immer null. Die richtige Spalte ist ordinal_position. Getestet in PG 9.4.
Greatvovan

1
@a_horse_with_no_name Ich habe eine von einem anonymen Benutzer vorgeschlagene Änderung genehmigt. Ich bin nicht sicher, ob die Bearbeitung erfolgreich sein wird, andere haben sie abgelehnt. Bitte überprüfen Sie in jedem Fall den obigen Vorschlag und den Kommentar von greatvovan. Ich denke sie sind korrekt und ordinal_positionsollten benutzt werden. Das position_in_unique_constraintist nicht nur im FKs-Gebrauch null.
ypercubeᵀᴹ

20

Dies ist eine genauere Antwort:

select tc.table_schema, tc.table_name, kc.column_name 
from  
    information_schema.table_constraints tc,  
    information_schema.key_column_usage kc  
where 
    tc.constraint_type = 'PRIMARY KEY' 
    and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema
    and kc.constraint_name = tc.constraint_name
order by 1, 2;

Sie haben das and kc.constraint_name = tc.constraint_nameTeil verpasst , daher werden alle Einschränkungen aufgelistet.


2
Während Ihre Abfrage funktioniert, ist der wichtigere Unterschied der fehlende and kc.position_in_unique_constraint is not nullTeil. Es wird dringend empfohlen, ANSI JOINs zu verwenden (obwohl dies für viele Geschmackssachen ist).
Dezso

1

Bitte beachten Sie dies auch. Dadurch wird das Skript zum Ändern aller Tabellen generiert.

SELECT STRING_AGG(FORMAT('ALTER TABLE %s CLUSTER ON %s;', A.table_name, A.constraint_name), E'\n') AS SCRIPT
FROM
(
    SELECT      FORMAT('%s.%s', table_schema, table_name) AS table_name, constraint_name
    FROM        information_schema.table_constraints
    WHERE       UPPER(constraint_type) = 'PRIMARY KEY'
    ORDER BY    table_name 
) AS A;

In der Frage wird nicht gefragt, wie die Tabellen geändert werden sollen.
Ypercubeᵀᴹ

1
Ich sehne mich danach, was @ ypercubeᵀᴹ sagt. Löschen Sie diese Antwort, aber lassen Sie sich nicht entmutigen. Nehmen Sie an der Tour teil, besuchen Sie die Hilfe und lesen Sie den Blog "Helfen Sie uns, Ihnen zu helfen". Was die Beantwortung von Fragen angeht, haben wir das schon oft gemacht :-). ps willkommen im forum!
Vérace

1

Ich denke, um Primärschlüssel und Fremdschlüssel zu erhalten, sollte dies tun. kc.position_in_unique_constraint ist nicht null. Diese Bedingung kann nur Fremdschlüssel abrufen.

select tc.table_schema, tc.table_name, kc.column_name,tc.constraint_type
from 
    information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kc 
        on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema 
                and kc.constraint_name = tc.constraint_name
where 
--kc.position_in_unique_constraint is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;

Ich versuche so etwas zu tun (die Tabellennamen sind etwas anders, ich bin wahrscheinlich auf einer anderen Version von Postgres). Die Abfrage wird ausgeführt, aber ich erhalte keine Ergebnisse zurück. Kann es sein, dass ich nicht die richtigen Berechtigungen habe?
Szeitlin
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.