Bạn có thể truy vấn danh mục hệ thống
cho các ràng buộc duy nhất , cụ thể là pg_constraint
và 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;
-
loại nhận dạng đối tượng
regclass
giúp xác định rõ ràng bảng của bạn. -
Chức năng thông tin danh mục hệ thống
pg_get_constraintdef()
cung cấp cho bạn thông tin được định dạng độc đáo, thông tin này không hoàn toàn cần thiết cho yêu cầu của bạn. -
Đồng thời sử dụng toán tử mảng
<@
và@>
để đảm bảo các mảng khớp hoàn toàn. (Thứ tự của các cột không xác định.) Các cột hệ thống làsmallint
vàsmallint[]
tương ứng. Truyền tớiinteger
để làm cho nó hoạt động với các toán tử đó. -
Tên cột có phân biệt chữ hoa chữ thường khi tra cứu trực tiếp trong danh mục hệ thống. Nếu bạn không trích dẫn kép
C1
vàC2
tại thời điểm tạo, bạn phải sử dụngc1
vàc2
trong bối cảnh này. -
Cũng có thể có một ràng buộc khóa chính nhiều cột thực thi tính duy nhất. Để đề cập đến điều đó trong truy vấn, hãy sử dụng:
WHERE c.contype IN ('u', 'p')
Được xây dựng dựa trên fiddle của @ Roman, cái này cũng thể hiện trường hợp pk:
Chỉ mục duy nhất
Cả hai điều trên (ràng buộc duy nhất &pk) đều được thực hiện theo cách của một chỉ mục duy nhất. Ngoài ra, cũng có thể có chỉ số duy nhất hoạt động hiệu quả giống như ràng buộc duy nhất được khai báo chính thức. Để nắm bắt tất cả chúng truy vấn danh mục hệ thống pg_index
thay vào đó, theo cách tương tự:
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;
Khó khăn đặc biệt ở đây là loại nội bộ int2vector
. Tôi xử lý nó bằng cách truyền văn bản và chuyển đổi thành int[]
.
Lưu ý rằng việc triển khai các bảng danh mục có thể thay đổi trên các lĩnh vực chính. Không có khả năng những truy vấn này bị hỏng, nhưng có thể.