2

最大値なしで 1 から始まるシーケンスを作成しました 主キーを自動的に挿入するためのトリガーを作成しました 主キーが一意で null でない必要があるテーブルの制約も設定しました

create trigger MY_TEMP_TRIGGER
before insert on MY_TEMP
for each row

BEGIN

  SELECT MY_TEMP_SEQ.nextval 
    INTO :new.Id 
    FROM DUAL;

END;
/

INSERT INTO my_temp  
  (Id,Type, CreateDT, TypeId, TempType, DevType, Msg, File,User, Src, SrcDev)   
VALUES
 (MY_TEMP_SEQ.nextval,3434,2843,2453,2392,435,2390,'pension.txt','rereee',454545,3434)

結果:

1 行目のエラー:
ORA-00001: 一意の制約 (USER.PK_MY_TEMP) に違反しています

テーブルMY_TEMPには、IDフィールドの1から338までの値がすでに含まれています

では、トリガーと挿入ステートメントでこれをどのように処理すればよいでしょうか。

4

3 に答える 3

1

挿入時に独自の ID 値を指定するオプションが本当に必要で、それ以外の場合はシーケンスを使用してトリガーに依存する場合、トリガーは値が渡されたかどうかを確認する必要があります。そうでない場合は、トリガーによって生成された ID が優先されます。 (そしてMY_TEMP_SEQ.nextval挿入で指定すると、その値はスキップされます)。

BEGIN
    IF :NEW.id IS NULL THEN
        SELECT MY_TEMP_SEQ.nextval 
        INTO :NEW.id 
        FROM DUAL;
    END IF;
END;

すでに存在する値を扱うのはより複雑です。独自の (シーケンスではない) ID 値を渡すつもりがない場合は、シーケンスを既存の最大値にロール フォワードすることができます。次に例を示します。

ALTER SEQUENCE MY_TEMP_SEQ INCREMENT BY 338; -- or however many you need to skip
SELECT MY_TEMP_SEQ.nextval FROM DUAL;
ALTER SEQUENCE MY_TEMP_SEQ INCREMENT BY 1;

問題が発生するのは、シーケンスを使用せずに ID 値を手動で指定してレコードを挿入しようとした場合です。これは、シーケンスよりも大きくなります (たとえば、500 を使用)。シーケンスが (最終的に) その値に到達しても、ORA-00001 が返されます。

トリガー内でそれ、または差し迫った問題を処理できるとは思いません。同じテーブル内の既存の値をチェックしようとすると、テーブルの変更エラーが発生すると思います。その回避策は、複雑さ (3 つのトリガーが必要) を追加し、不安定になる可能性があります。私が知る限り、そのシナリオに対処する唯一の簡単な方法は、代わりに挿入をプロシージャでラップし、直接挿入をブロックすることですが、これもオプションではない可能性があります。ただし、シーケンスを使用せずに値を挿入する場合にのみ、これについて心配する必要があります。

于 2011-05-19T08:33:21.227 に答える
0

トリガーをインストールする前に、シーケンスをインクリメントできます。

declare 
  v_max_id my_temp.id%type;
  v_curr_seq  NUMBER;
begin
  select max(id) into v_max_id from my_temp;

  loop
    select MY_TEMP_SEQ.nextval into v_curr_seq from dual;
    exit when v_curr_seq >= v_max_id;
  end loop;
end;
/
于 2011-05-19T08:31:08.560 に答える