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;