Anda dapat menanyakan katalog sistem
untuk batasan unik , khususnya pg_constraint
dan 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;
-
Jenis pengenal objek
regclass
membantu mengidentifikasi tabel Anda dengan jelas. -
Fungsi informasi katalog sistem
pg_get_constraintdef()
memberi Anda informasi yang diformat dengan baik, yang tidak sepenuhnya diperlukan untuk permintaan Anda. -
Juga menggunakan operator array
<@
dan@>
untuk memastikan array benar-benar cocok. (Urutan kolom tidak diketahui.) Kolom sistemsmallint
dansmallint[]
masing-masing. Transmisikan keinteger
untuk membuatnya bekerja dengan operator tersebut. -
Nama kolom peka huruf besar/kecil saat mencarinya di katalog sistem secara langsung. Jika Anda tidak mengutip dua kali
C1
danC2
pada waktu pembuatan, Anda harus menggunakanc1
danc2
dalam konteks ini. -
Mungkin juga ada batasan kunci utama multikolom menegakkan keunikan. Untuk menutupinya dalam kueri gunakan sebagai gantinya:
WHERE c.contype IN ('u', 'p')
Membangun biola @Roman, yang ini juga menunjukkan kasus pk:
Indeks unik
Kedua hal di atas (kendala unik &pk) diimplementasikan melalui indeks unik. Selain itu bisa juga ada indeks unik melakukan secara efektif sama dengan batasan unik yang dinyatakan secara formal. Untuk menangkap semuanya kueri katalog sistem pg_index
sebagai gantinya, dengan cara yang sama:
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;
Kesulitan khusus di sini adalah tipe internal int2vector
. Saya mengatasinya dengan mentransmisikan teks dan mengonversi ke int[]
.
Ketahuilah bahwa implementasi tabel katalog mungkin berubah di seluruh jurusan. Tidak mungkin kueri ini rusak, tetapi mungkin.