Du kan fråga systemkatalogerna
för unika begränsningar , särskilt pg_constraint
och 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;
-
objektidentifieringstypen
regclass
hjälper till att entydigt identifiera din tabell. -
Systemkataloginformationsfunktionen
pg_get_constraintdef()
ger dig snyggt formaterad information, vilket inte är absolut nödvändigt för din begäran. -
Använder även arrayoperatorer
<@
och@>
för att se till att arrayerna matchar helt. (Kolumnernas ordning är okänd.) Systemkolumnerna ärsmallint
ochsmallint[]
respektive. Casta tillinteger
för att få det att fungera med dessa operatörer. -
Kolumnnamn är skiftlägeskänsliga när du letar upp dem direkt i systemkatalogen. Om du inte dubbelciterade
C1
ochC2
vid skapandet måste du användac1
ochc2
i detta sammanhang. -
Det kan också finnas en primär nyckelbegränsning med flera kolumner upprätthålla unikhet. För att täcka det i frågan använd istället:
WHERE c.contype IN ('u', 'p')
Med utgångspunkt i @Romans fiol, visar den här också pk-fallet:
Unikt index
Båda ovanstående (unika &pk-begränsningar) implementeras med hjälp av ett unikt index. Dessutom kan det också finnas unika index gör i praktiken samma sak som formellt deklarerade unika begränsningar. För att fånga alla fråga systemkatalogen pg_index
istället på ett liknande sätt:
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;
Speciell svårighet här är den interna typen int2vector
. Jag hanterar det genom att casta text och konvertera till int[]
.
Var medveten om att implementeringen av katalogtabeller kan ändras över huvud. Osannolikt att dessa frågor går sönder, men möjligt.