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
regclassgiú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àsmallintvà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
C1vàC2tại thời điểm tạo, bạn phải sử dụngc1vàc2trong 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ể.