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

ONCONFLICTに一致する一意の制約または除外制約はありません

    ドキュメントによると、

    順序に関係なく、conflict_targetで指定された列/式を正確に含むすべてのtable_name一意のインデックスは、arbiterindexesとして推測(選択)されます。 index_predicateが指定されている場合、推論のさらなる要件として、アービターインデックスを満たす必要があります。

    ドキュメントは続けて言います、

    [index_predicateは、部分的に一意のインデックスの推論を可能にするために使用されます

    控えめに言って、ドキュメントは、部分インデックスを使用してON CONFLICTでアップサーティングする場合、index_predicateを指定する必要があると言っています。 。それはあなたのために推測されていません。私はここでこれを学びました、そして次の例はこれを示しています。

    CREATE TABLE test.accounts (
        id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
        type text,
        person_id int);
    CREATE UNIQUE INDEX accounts_note_idx on accounts (type, person_id) WHERE ((type)::text = 'PersonAccount'::text);
    INSERT INTO  test.accounts (type, person_id) VALUES ('PersonAccount', 10);
    

    unutbu=# select * from test.accounts;
    +----+---------------+-----------+
    | id |     type      | person_id |
    +----+---------------+-----------+
    |  1 | PersonAccount |        10 |
    +----+---------------+-----------+
    (1 row)
    

    index_predicateなし エラーが発生します:

    INSERT INTO  test.accounts (type, person_id) VALUES ('PersonAccount', 10) ON CONFLICT (type, person_id) DO NOTHING;
    -- ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
    

    ただし、代わりにindex_predicateを含めると、WHERE ((type)::text = 'PersonAccount'::text)

    INSERT INTO  test.accounts (type, person_id) VALUES ('PersonAccount', 10)
    ON CONFLICT (type, person_id)
    WHERE ((type)::text = 'PersonAccount'::text) DO NOTHING;
    

    その後、エラーは発生せず、何も尊重されません。



    1. MariaDBでのADDTIME()のしくみ

    2. PostgreSQLで平均を小数点以下2桁に丸める方法は?

    3. CentOS / RHEL7およびDebian8/9でMariaDB(マスタースレーブ)レプリケーションをセットアップする方法

    4. ProxySQLロードバランサーをクラスター化する方法