0

SQL Developer (Oracle 11g XPRESS) で重複エントリの挿入を防ぐトリガーを作成しようとしましたが、正しくコンパイルされません。構文に明らかなエラーが見られないので、理由を教えてください。

CREATE OR REPLACE TRIGGER trig1

BEFORE INSERT ON table1

BEGIN 
  DECLARE CURSOR C1
  IS
    SELECT value1,value2 FROM inserted;

  DECLARE value11 number;
  DECLARE value22 number;
  OPEN C1;
  FETCH NEXT FROM C1 INTO @value11, @value22;

  WHILE FETCH_STATUS = 0
  LOOP
    IF NOT EXISTS (SELECT * FROM table1 WHERE value1 = @value11 AND value2 = @value22)
    THEN
        INSERT INTO table1 (value1,value2)
        VALUES
        (@value11, @value22);
    ELSE
        ROLLBACK TRANSACTION
        --DELETE FROM table1 WHERE value1 = @value11 AND value2 = @value22
        PRINT 'Cannot add duplicate entry.'
    END IF;
    FETCH NEXT FROM C1 INTO @value11, @value22;
  END LOOP; 
  CLOSE C1;
END;
4

1 に答える 1

1

トリガーに関する問題のほとんどは、間違った構文を使用していることが原因です。これは PL/SQL ではなく MySQL のようです。続行する前に、ドキュメントを読み、いくつかの例を確認することをお勧めします。

そうは言っても; あなたはこれについてすべて間違った方法で行っています。重複の挿入を防ぐために、テーブルに一意の制約を作成する必要があります。それが確実に防止できる唯一の方法です。コードでそれを回避しようとすると、ある時点で失敗することになります。

一意の制約をインラインで作成するか、テーブルが既に存在する場合は、一意のインデックスを作成できます。

CREATE UNIQUE INDEX index_name
    ON table_name (column1, column2, ... column_n);

または ALTER TABLE ステートメントを使用します。

ALTER TABLE table_name
  add CONSTRAINT constraint_name UNIQUE (column1, column2, ... column_n);

テスト対象の列のセットが主キーである場合は、代わりに主キー制約を追加できます。

一意の制約を有効にすると、ユーザーが何を決定しても整合性が強制されるだけでなく、データを挿入してエラーをキャッチするだけで済みます。挿入前にテーブルにクエリを実行する必要がないため、アプリケーションが高速化されます。

于 2013-02-05T20:37:37.000 に答える