U kunt de systeemcatalogi
opvragen voor unieke beperkingen , in het bijzonder pg_constraint
en 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;
-
Het type objectidentificatie
regclass
helpt om uw tafel ondubbelzinnig te identificeren. -
De informatiefunctie van de systeemcatalogus
pg_get_constraintdef()
krijgt u mooi opgemaakte informatie, die niet strikt noodzakelijk is voor uw verzoek. -
Ook met behulp van array-operators
<@
en@>
om ervoor te zorgen dat de arrays volledig overeenkomen. (De volgorde van de kolommen is onbekend.) De systeemkolommen zijnsmallint
ensmallint[]
respectievelijk. Casten naarinteger
om het met die operators te laten werken. -
Kolomnamen zijn hoofdlettergevoelig wanneer u ze rechtstreeks in de systeemcatalogus opzoekt. Als je
C1
niet dubbel hebt gequote enC2
bij het maken moet jec1
. gebruiken enc2
in deze context. -
Er kan ook een primaire sleutelbeperking met meerdere kolommen zijn uniciteit afdwingen. Gebruik in plaats daarvan om dat in de query te behandelen:
WHERE c.contype IN ('u', 'p')
Voortbouwend op de viool van @Roman, demonstreert deze ook de pk-zaak:
Unieke index
Beide bovenstaande (unieke en pk-beperkingen) worden geïmplementeerd door middel van een unieke index. Daarnaast kunnen er ook unieke indices . zijn doet in feite hetzelfde als formeel verklaarde unieke beperking. Om allemaal te vangen doorzoek de systeemcatalogus pg_index
in plaats daarvan, op een vergelijkbare manier:
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;
Speciale moeilijkheid hier is het interne type int2vector
. Ik behandel het door tekst te casten en te converteren naar int[]
.
Houd er rekening mee dat de implementatie van catalogustabellen kan veranderen in de belangrijkste. Het is onwaarschijnlijk dat deze zoekopdrachten kapot gaan, maar het is mogelijk.