Lista kluczy podstawowych dla wszystkich tabel - Postgresql


14

Czy istnieje takie zapytanie?

Znalazłem kilka zapytań, które mogą to zrobić dla jednej tabeli, ale nie byłem w stanie go zmodyfikować, więc widzę:

tablename | column | type

1
Gdybym o to pytał, chciałbym poznać porządkową pozycję kolumny w PK (niektóre PK mają więcej niż 1 kolumnę i kolejność może mieć znaczenie).
ypercubeᵀᴹ

Odpowiedzi:


13

Coś takiego:

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;

To zapytanie pokazuje nie tylko klucze podstawowe, ale także unikalne indeksy
Michał Niklas

@ MichałNiklas nie.
dezso

1
@DarielPratama: warunek tc.constraint_type = 'PRIMARY KEY'pokaże tylko klucze podstawowe. Jednak każdy klucz podstawowy jest chroniony unikalnym indexe
a_horse_w__na_name

2
@ a_horse_with_no_name Uważam, że jest to niepoprawne. position_in_unique_constraintwskazuje pozycję klucza OBCEGO, dla kluczy podstawowych zawsze jest pusta. Prawidłowa kolumna to ordinal_position. Testowane w PG 9.4.
greatvovan

1
@ a_horse_with_no_name Zatwierdziłem edycję sugerowaną przez anonimowego użytkownika. Nie jestem pewien, czy edycja zostanie wykonana, inni odrzucili. W każdym razie sprawdź sugestię i powyższy komentarz greatvovan. Myślę, że są poprawne i ordinal_positionpowinny być używane. Nie position_in_unique_constraintjest zerowy tylko w użyciu FK.
ypercubeᵀᴹ

20

To jest dokładniejsza odpowiedź:

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;

Brakowało and kc.constraint_name = tc.constraint_nameczęści, więc zawiera listę wszystkich ograniczeń.


2
Podczas gdy twoje zapytanie działa, najważniejszą różnicą jest brakująca and kc.position_in_unique_constraint is not nullczęść. I gorąco zachęcamy do korzystania z ANSI JOIN (choć wielu uważa, że ​​to kwestia gustu).
dezso,

1

Weź to również pod uwagę. Spowoduje to wygenerowanie skryptu do zmiany wszystkich tabel.

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;

Pytanie nie pyta, jak zmienić tabele.
ypercubeᵀᴹ

1
Popieram to, co mówi @ ypercube. Usuń tę odpowiedź, ale nie zniechęcaj się - obejrzyj przewodnik, odwiedź centrum pomocy i przeczytaj blog „pomóż nam pomóc”. Jeśli chodzi o odpowiedź na coś, o co nie pytano, wszyscy robiliśmy to wiele razy :-). ps witamy na forum!
Vérace

1

Myślę, że klucz podstawowy i klucz obcy powinny zrobić tak. kc.position_in_unique_constraint nie ma wartości NULL, warunek ten może uzyskać tylko klucze obce.

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;

Próbuję zrobić coś takiego (nazwy tabel są nieco inne, prawdopodobnie używam innej wersji postgres). Zapytanie jest uruchamiane, ale nie otrzymuję żadnych wyników. Czy to możliwe, że nie mam odpowiednich uprawnień?
szeitlin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.