sql >> データベース >  >> RDS >> PostgreSQL

特定の列に一意キー制約が存在するかどうかを確認する方法

    システムカタログ にクエリを実行できます 固有の制約の場合 、特に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ケースも示しています:

    -> SQLfiddle

    一意のインデックス

    上記の両方(一意の制約と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[]に変換することで対処します 。

    カタログテーブルの実装はメジャー間で変更される可能性があることに注意してください。これらのクエリが機能しなくなる可能性は低いですが、可能です。



    1. mysqlは複数の列の配列です

    2. MySQL、ORDER BY挿入順序、並べ替え列なし

    3. MysqlDBからJFreechartTimeSeriesCollectionにデータを入力しますか?

    4. 3 列の SQL PIVOT