2

テーブルの代理キーを生成するための次のタイプのパターンを持つコードベースに取り組んでいます。

create or replace
TRIGGER TEST_TRIG
BEFORE INSERT  OR UPDATE
ON my_table
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
BEGIN
   IF INSERTING THEN
      IF NVL(:NEW.column1, 0) = 0 THEN
         SELECT my_table_seq.NEXTVAL
         INTO  :NEW.column1
         FROM  dual;

      END IF;
   END IF;
END;

そして、このコードを呼び出すPL/SQLロジックは、

begin
     insert into my_table(0);
end;

私の質問は、トリガーの必要性は何ですか? なぜ、

insert into my_table(my_table_seq.next_val)

そしてそれを一日と呼びますか?どんな洞察も大歓迎です。ありがとう。

4

2 に答える 2

3

この特定のパターンは、誰かが新しい ID を手動で入力することを可能にするため、実際には非常に危険です。この ID は、既に存在する代理キーまたはシーケンスが将来生成する可能性のある代理キーと衝突する可能性があります。

新しいレコードごとに一意のキーが取得されるようにするには、トリガーは実際には次のようにする必要があります。11.2 以降を使用している場合は、select ... into ...

CREATE OR REPLACE TRIGGER TEST_TRIG
BEFORE INSERT ON my_table
FOR EACH ROW
BEGIN
   :new.column1 := my_table_seq.NEXTVAL;
END;

このアプローチの利点は、常に実行されることです。誰かがこの列に入力した値は、機能し、正しい順序を使用するものに上書きされます。誰かがそれをステートメントに追加するのを忘れた場合でも機能します。

これにより、代理キーを破ることができなくなります。

あなたが提案したことで、誰かが代わりに 1 を置いたと想像してください。主キー違反が発生します。誰かが忘れると、さらにエラーが発生します。テーブルへのすべての更新が単一のエントリ ポイントを介して行われることを保証することはできないため、トリガーは PK が正しく入力されることを保証します。

12c から、テーブルと自動インクリメントの間のリンクを明示するID 列を使用できることに注意してください。トリガーやシーケンスは必要ありません。テーブル作成 DDL の構文は次のようになります。

create table <table_name> ( <column_name> generated as identity );
于 2013-07-26T11:47:14.670 に答える