postgresql - 問題のないすべてのレコードを INSERT するための一意のキー違反をスキップします

okwaves2024-01-25  9

Postgres テーブルには、主キー (自動生成) とさらに一意制約があります。

現在: SELECT ステートメントを使用した INSERT 中に、重複 (一意制約) に違反すると、何も INSERT されません。

要件: 重複が発生した場合は、それらのレコードをスキップし、一時テーブルでキャッチし、問題のないすべてのレコードの INSERT を続行する必要があります (制約の問題なし)

テーブル構造:

CREATE TABLE invoice_output (
    id SERIAL,
    title TEXT UNIQUE NOT NULL,
    description TEXT NOT NULL,
    CONSTRAINT Invoice_pk PRIMARY KEY(id),
    CONSTRAINT title_unique UNIQUE(title)
);

次のように挿入を行う関数を呼び出します。

CREATE OR REPLACE FUNCTION public.fn_create_invoice_output(<params>)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
...

BEGIN
  INSERT INTO public.invoice_output(id,title,description)
  SELECT id,title,description FROM public.invoice_input;

    IF NOT FOUND THEN
      RAISE WARNING  'fn_create_invoice_header_output() - job id or client not found';
      status := -1;
    END IF;

   RETURN status;

END;

$function$
;

SQL エラー [23505] が発生します: エラー: 重複したキー値が一意の制約に違反しています。

重複しないもののみが挿入およびコミットされるように例外を作成するにはどうすればよいですか。重複のキーは挿入からスキップし、キャプチャして印刷できます。アウト

挿入ステートメントの後にこれを試してみました

EXCEPTION WHEN unique_violation THEN RAISE NOTICE 'row skipped in  public.fn_create_invoice_output ';

それとも、挿入コマンドの選択ステートメントの結果セットを反復処理できますか?そうすれば簡単に実行できますか?

postgresql.org/docs/9.5/sql-insert.html#SQL-ON-CONFLICT を参照してください。

– マフォー

2020 年 9 月 4 日 17:42



------------------------

ON CONFLICT を使用できます。

INSERT INTO public.invoice_output (id,title,description)
SELECT id,title,description 
FROM public.invoice_input
ON CONFLICT DO NOTHING;

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。