Du kan forespørge i systemkatalogerne
for unikke begrænsninger , især pg_constraint og 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;
-
objektidentifikationstypen
regclasshjælper med entydigt at identificere dit bord. -
Systemkataloginformationsfunktionen
pg_get_constraintdef()får dig pænt formateret information, hvilket ikke er strengt nødvendigt for din anmodning. -
Bruger også array-operatorer
<@og@>for at sikre, at arrays matcher fuldstændigt. (Rækkefølgen af kolonner er ukendt.) Systemkolonnerne ersmallintogsmallint[]henholdsvis. Cast tilintegerfor at få det til at fungere med disse operatører. -
Kolonnenavne skelner mellem store og små bogstaver, når de slås direkte op i systemkataloget. Hvis du ikke har citeret
C1dobbelt ogC2på oprettelsestidspunktet skal du brugec1ogc2i denne sammenhæng. -
Der kan også være en primær nøglebegrænsning med flere kolonner håndhævelse af unikhed. For at dække det i forespørgslen, brug i stedet:
WHERE c.contype IN ('u', 'p')
Med udgangspunkt i @Romans violin, demonstrerer denne også pk-sagen:
Unikt indeks
Begge ovenstående (unikke &pk-begrænsninger) er implementeret ved hjælp af et unikt indeks. Derudover kan der også være unikke indekser gør effektivt det samme som formelt erklæret unik begrænsning. For at fange dem alle forespørg på systemkataloget pg_index
i stedet på lignende måde:
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;
Særlig vanskelighed her er den interne type int2vector . Jeg håndterer det ved at caste tekst og konvertere til int[] .
Vær opmærksom på, at implementering af katalogtabeller kan ændre sig på tværs af store. Usandsynligt, at disse forespørgsler går i stykker, men muligt.