Możesz wysłać zapytanie do katalogów systemowych
dla unikalnych ograniczeń , w szczególności pg_constraint
i pg_attribute
:
SELECT c.conname, pg_get_constraintdef(c.oid)
FROM pg_constraint c
JOIN (
SELECT array_agg(attnum::int) AS attkey
FROM pg_attribute
WHERE attrelid = 'tb'::regclass -- table name optionally schema-qualified
AND attname = ANY('{c1,c2}')
) a ON c.conkey::int[] <@ a.attkey AND c.conkey::int[] @> a.attkey
WHERE c.contype = 'u'
AND c.conrelid = 'tb'::regclass;
-
typ identyfikatora obiektu
regclass
pomaga jednoznacznie zidentyfikować Twój stół. -
Funkcja informacji o katalogu systemowym
pg_get_constraintdef()
dostarcza ładnie sformatowanych informacji, które nie są bezwzględnie konieczne dla Twojego żądania. -
Również przy użyciu operatorów tablicowych
<@
i@> aby upewnić się, że tablice są całkowicie dopasowane. (Kolejność kolumn jest nieznana.) Kolumny systemowe są
smallint
ismallint[]
odpowiednio. Przesyłaj doliczby całkowitej
aby działało z tymi operatorami. -
W nazwach kolumn rozróżniana jest wielkość liter podczas bezpośredniego wyszukiwania ich w katalogu systemowym. Jeśli nie umieściłeś podwójnego cudzysłowu
C1
iC2
w czasie tworzenia musisz użyćc1
ic2
w tym kontekście. -
Może również istnieć wielokolumnowe ograniczenie klucza podstawowego egzekwowanie wyjątkowości. Aby uwzględnić to w zapytaniu, użyj zamiast tego:
WHERE c.contype IN ('u', 'p')
Opierając się na skrzypcach @Roman, ten pokazuje również przypadek pk:
Unikalny indeks
Oba powyższe (ograniczenia unikalne i pk) są implementowane za pomocą unikalnego indeksu. Ponadto mogą istnieć również unikalne indeksy robiąc skutecznie to samo, co formalnie zadeklarowane ograniczenie unikatowe. Aby złapać wszystkie przeszukaj katalog systemowy pg_index
zamiast tego w podobny sposób:
SELECT c.relname AS idx_name
FROM (
SELECT indexrelid, string_to_array(indkey::text, ' ')::int[] AS indkey
FROM pg_index
WHERE indrelid = 'tb'::regclass
AND indisunique -- contains "indisprimary"
) i
JOIN (
SELECT array_agg(attnum::int) AS attkey
FROM pg_attribute
WHERE attrelid = 'tb'::regclass
AND attname = ANY('{c1,c2}')
) a ON i.indkey <@ a.attkey AND i.indkey @> a.attkey
JOIN pg_class c ON c.oid = i.indexrelid;
Szczególną trudnością jest tutaj typ wewnętrzny int2vector
. Zajmuję się tym, przesyłając tekst i konwertując do int[]
.
Należy pamiętać, że implementacja tabel katalogu może ulec zmianie w zależności od głównych. Jest mało prawdopodobne, że te zapytania się zepsują, ale możliwe.