データベースのトレースされた挿入のセットがあり、それらを別の同様の挿入に発行したい。問題は、同様のデータベースに挿入しようとしているキーが既にあるため、制約違反エラーが発生することです。
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39822, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39823, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39824, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39825, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
エラー:
*原因:UPDATEまたはINSERTステートメントが重複キーを挿入しようとしました。 DBMS MACモードで構成されたTrusted Oracleの場合、異なるレベルに重複するエントリが存在すると、このメッセージが表示されることがあります。 *アクション:一意の制限を削除するか、キーを挿入しないでください。
私の質問:この問題を回避し、すでに存在する場合に別のキー値を挿入するようにデータベースに指示する方法はありますか?他の列の値を保持することも重要です。
私はすでにいくつかの可能な解決策を探しましたが、最善のアプローチはそれを処理するためにPL/SQL例外を使用することです。どうすればいいのか今まで分からない。
DECLARE
BEGIN
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39822, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39823, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39824, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
INSERT INTO "COMPONENTS" ( "ID_COMPONENT", "CODE", "DESCRIPTION", "MODEL", "RESP" ) VALUES
(39825, "101087632", "COMPONENT TEST", "TEST", "ADMIN");
exception
when DUP_VAL_ON_INDEX then
--do the insert. but how?
END;
助言がありますか?前もって感謝します。
EXCEPTION
を使用して重複キーなどのロジック/処理を行うことは、おそらくベストプラクティスではないと思います。これがアイデアです:ストアドプロシージャを記述します。また、重複するキーの場合に使用される代替値を持つシーケンスを作成します。このシーケンスを1,000,000などのかなり高い値(または実際のデータに応じてはるかに高い値)から開始することができます。次に、dupe-sub機能が必要なときはいつでも、このストアドプロシージャを介して挿入を実行します。
CREATE TABLE components (
id_component INTEGER PRIMARY KEY
, code VARCHAR2(255)
, description VARCHAR2(255)
, model VARCHAR2(255)
, resp VARCHAR2(255)
);
CREATE SEQUENCE components_alt_id_seq
START WITH 1000000;
CREATE OR REPLACE PROCEDURE component_ins
( p_id_component IN components.id_component%TYPE
, p_code IN components.code%TYPE
, p_description IN components.description%TYPE
, p_model IN components.model%TYPE
, p_resp IN components.resp%TYPE )
AS
v_is_duplicate INTEGER;
BEGIN
SELECT count(*) INTO v_is_duplicate FROM components WHERE id_component = p_id_component;
IF v_duplicate = 0 THEN
INSERT INTO components (id_component, code, description, model, resp)
VALUES (p_id_component, p_code, p_description, p_model, p_resp);
ELSE
INSERT INTO components (id_component, code, description, model, resp)
VALUES (components_alt_id_seq.NEXTVAL, p_code, p_description, p_model, p_resp);
END IF;
END;
/
EXEC component_ins (39822, '101087632', 'COMPONENT TEST', 'TEST', 'ADMIN')
EXEC component_ins (39823, '101087632', 'COMPONENT TEST', 'TEST', 'ADMIN')
EXEC component_ins (39824, '101087632', 'COMPONENT TEST', 'TEST', 'ADMIN')
EXEC component_ins (39822, '101087632', 'COMPONENT TEST', 'TEST', 'ADMIN')
EXEC component_ins (39822, '101087632', 'COMPONENT TEST', 'TEST', 'ADMIN')
EXEC component_ins (40015, '101087632', 'COMPONENT TEST', 'TEST', 'ADMIN')
EXEC component_ins (40016, '101087632', 'COMPONENT TEST', 'TEST', 'ADMIN')
そして、結果を確認しました。重複する入力値には、シーケンスから取得した値が自動的に追加されていることに注意してください。
SELECT id_component FROM components;
ID_COMPONENT
------------
39822
39823
39824
40015
40016
1000005
1000006
7 rows selected.