2016-10-20 11 views
0

1つのフィールドが1つの値に設定されている前の項目がある場合は、項目の追加または更新ができないトリガーを作成します。これは、以来、動作しないはずです固有の列のトリガー

insert into table_name (name, type, description,...) 
values ('Manuel', 'HUMAN', 'first entry', ...) 

を:私はこのような新しいエントリを追加したい場合は

id name   type, description, (some other fields) 
1 'Manuel'  'HUMAN' ... 
2 'Manuel'  'DOG' ... 
3 'Other name' 'HUMAN' ... 

Let'sは、次のような表がある

±例を置きますManuelという名前の別のHUMAN型を追加することは許されません。

しかし、これを行うために許可する必要があります。基本的な考え方は、それぞれの名前のために、ということですので、

insert into table_name (name, type, description, ...) values ('Manuel', 'DOG', 'another description') 

(:)より良い例を見つけることができないため申し訳ありませんが)

を1つのHUMANエントリータイプしか許されてはいけません。

私はこのトリガーを作成し、それが動作していない:

CREATE OR REPLACE TRIGGER TABLE_TYPE_REL 
BEFORE INSERT OR UPDATE ON table_name 
REFERENCING NEW AS NEW OLD AS OLD 
FOR EACH ROW 
WHEN (NEW.TYPE = 'HUMAN') 
declare @check int 

select @check = count(*) 
from table_name as f 
where f.type = 'HUMAN' 

if @check <> 0 
begin 
    rollback transaction 
    raiserror('Only one name, human is allowed.', 16, 1) 
end 

ヒント?

+2

行を含む関数ベースのインデックスをしたいようですね

「)私はあなたがトリガー – Kritner

+2

以上のユニークな制約がこのやり過ぎではないですしたいと思いますか?トリガよりも(名前、型)の唯一の制約が十分で頑強ではないでしょうか? – Boneist

+0

Oracleの質問に対してMS SQLサーバーコードを表示しているのはなぜですか? – OldProgrammer

答えて

4

あなたのタグは、あなたがOracleを使用していると言います。あなたが掲示したトリガーコードは、SQL Server用です。私はあなたが実際にOracleを使用していると仮定し、あなたのトリガーが「機能していない」理由は間違った言語で書かれているということです(脇に、エラースタックを含めるのは本当に役に立ちます。あなただけtype='HUMAN'

CREATE UNIQUE INDEX idx_one_human 
    ON table_name(CASE WHEN type = 'HUMAN' 
         THEN name 
         ELSE null 
        END); 
+1

@Manuelarte - 一般的な原則として、トリガーを「最後の手段」とみなし、他のすべてが失敗した場合にのみ使用するツールを考えます。あなたがそれらを使って解決策を見つけることができるとき、制約とインデックスはずっと良い選択です。 Namaste Justinは、シンプルでエレガントで信頼性の高いソリューションです。 – mathguy

+0

@JustinCaveあなたの答えに感謝します。それがまさに私たちが望むものです。それが起こる唯一の事は、ユニークなインデックスを満たしていないと、エラーメッセージが100%読み込みできない可能性があります。 – Manuelarte

+0

@Manuelarte - カスタムエラーメッセージで例外を発生させたい場合、いつも 'dup_val_on_index'例外をキャッチして' raise_application_error'を使ってカスタム例外を発生させることができます。 –