システムカタログ
にクエリを実行できます 固有の制約の場合 、特にpg_constraint
および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;
-
オブジェクト識別子のタイプ
regclass
テーブルを明確に識別するのに役立ちます。 -
システムカタログ情報関数
pg_get_constraintdef()
適切にフォーマットされた情報を取得しますが、これはリクエストに厳密に必要なわけではありません。 -
また、配列演算子 を使用します
<@
および@>
アレイが完全に一致することを確認します。 (列の順序は不明です。)システム列はsmallint
です。 およびsmallint[]
それぞれ。integer
にキャストします それらの演算子で機能させるためです。 -
システムカタログで列名を直接検索する場合、列名では大文字と小文字が区別されます。
C1
を二重引用符で囲まなかった場合 およびC2
作成時に、c1
を使用する必要があります およびc2
この文脈で。 -
複数列の主キー制約が存在する可能性もあります 独自性を強制します。代わりにクエリでそれをカバーするには:
WHERE c.contype IN ('u', 'p')
@Romanのフィドルに基づいて、これはpkケースも示しています:
一意のインデックス
上記の両方(一意の制約とpk制約)は、一意のインデックスを使用して実装されます。さらに、一意のインデックスも存在する可能性があります 正式に宣言された一意性制約と実質的に同じことを行います。 すべてをキャッチするには システムカタログをクエリするpg_index
代わりに、同様の方法で:
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;
ここで特に難しいのは、内部型int2vector
です。 。テキストをキャストしてint[]
に変換することで対処します 。
カタログテーブルの実装はメジャー間で変更される可能性があることに注意してください。これらのクエリが機能しなくなる可能性は低いですが、可能です。