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
regclass
hjæ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 ersmallint
ogsmallint[]
henholdsvis. Cast tilinteger
for 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
C1
dobbelt ogC2
på oprettelsestidspunktet skal du brugec1
ogc2
i 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.