あなたが最終値の状態を強制します。したがって、挿入と更新の両方に:NEW
を使用する必要があります。
if :new.colA = 1
and (:new.colB != 0 or :new.colC != 1)
then
-- or whatever you want to happen ....
raise_application_error(-20000, 'your message here');
end if;
また、表にCHECK制約を使用することを検討する必要があります。制約はトリガーよりも効率的であり、このようなビジネスルールを実施するための業界標準アプローチです。
SQL> alter table t23 add constraint t23ck
2 check ((cola=1 and colb=0 and colc=1)
3 or cola != 1)
4/
Table altered.
SQL> insert into t23 (cola, colb, colc) values (1, 0 , 1);
1 row created.
SQL> insert into t23 (cola, colb, colc) values (1, 0 , 2);
insert into t23 (cola, colb, colc) values (1, 0 , 2)
*
ERROR at line 1:
ORA-02290: check constraint (FOX.T23CK) violated
SQL> insert into t23 (cola, colb, colc) values (0, 0 , 2);
1 row created.
SQL>
「ユーザーがこれだけ1列の値を提供している場合:他の列のためのNEWは何も持っていない私は、既存の値が必要になりますので。(:OLD)。条件チェックのために」
Fnord。 :NEW値は、変更された値ではなく、レコードの新しいバージョンを意味します。簡単なテストでこの動作を調べるのは簡単です:
SQL> create or replace trigger t23_upd_trg
2 before update on t23 for each row
3 begin
4 dbms_output.put_line ('new colA ='||:new.colA);
5 dbms_output.put_line ('new colB ='||:new.colB);
6 dbms_output.put_line ('new colC ='||:new.colC);
7 end;
8/
Trigger created.
SQL> set serveroutput on
SQL> select * from t23
2 where cola = 9
3/
COLA COLB COLC
---------- ---------- ----------
9 4 4
SQL> update t23
2 set cola = 1
3 where cola = 9
4/
new colA =1
new colB =4
new colC =4
update t23
*
ERROR at line 1:
ORA-02290: check constraint (FOX.T23CK) violated
参照してください。 :NEW.colb
および:NEW.colc
は、それらが最新のままであるため、元の値を返します。
「場合:OLD値が明示的にチェック状態で提供され、その後、:NEWはまだ何も値がユーザによってその列のために提供されていない場合には、レコードの新しいバージョンになりますか?」
:old
および:new
は、異なるバージョンのレコードを参照するための名前空間です。 :new
の値は、トランザクションの最後にテーブルに保持される値です。 update文で列の値が設定されていない場合は、:new.whatever = :old.whatever
です。
出典
2017-03-18 16:16:03
APC
ご回答いただきありがとうございます。私は実際に制約を使用しています。トリガコードが(コードビルダロジックを介して)生成されると、制約チェックはトリガロジックの一部になります。だから、もし制約が壊れるならば、私はログテーブルに(トリガ自体で)エントリを作らなければなりません。 –
こんにちは、あなたの決断について1つの質問。ユーザーがある列に対してのみ値を提供する場合、他の列のNEWには何もありません。条件チェックには既存の値(:OLD)が必要になります。このシナリオをどのように処理するのですか? –
詳細な説明をありがとう。もう1つの質問。もし:OLD値がチェック条件に明示的に与えられていれば、その列に対してユーザによって値が与えられていない場合、NEWはまだレコードの新しいバージョンとなるでしょうか? –