トリガーにはいくつかの問題があります。 select ステートメントと残りのコードの間の「関係」から始めましょう。この特定のケースでは、select..
そして if...end_if
(今のところ、選択が実際に機能すると仮定しますが、そうではなく、単に仮定します)。ここで、WHERE 句に集中してください。
SELECT SUPPLIER.TRUSTED_SUPPLIER INTO TRUST ... WHERE SUPPLIER.TRUSTED_SUPPLIER = 'YES'; IF TRUST = 'NO' THEN ...
プレ>select は YES のみを返すため、if ステートメントが True になることはありません。したがって、アプリケーション例外が発生することはありません。さて、
select
の問題点は何ですか? .
まず、トリガーが起動されるテーブルにアクセスします。場合によっては回避できますが、通常は ORA が発生します-04091:テーブルは変化しています。トリガー/関数はそれを認識しない可能性があります .トリガー テーブルを完全に参照することを常に回避することはできません。 :NEW および/または :OLD 疑似レコードを使用してテーブル データを参照します。第二に、あなたのクエリはあなたが思っていることをしていません。ただし、INTO 句では、正確に 1 行を返すステートメントが必要です。 . 1 行を超えると例外が発生し、0 行の場合は
no data found
になります 例外。
最後に、raise_application_error statement
に問題があります .実行された場合、number 引数が発生します... is out of range 例外。最初のパラメーターは -20999 から -20000 (負の数) の間でなければなりません。結果は次のようになります:create or replace trigger verify_supplier_trust before insert or update on product for each row declare trust varchar2(3); begin select supplier.trusted_supplier into trust from supplier where supplier.company_name = :new.supplier_name and supplier.trusted_supplier = 'YES'; exception when no_data_found then raise_application_error(-20001, 'supplier not trusted'); end; /
プレ>注:
データ型 VARCHAR は使用しないでください。許可されていますが、オラクル社は推奨していません。いつでも何をするかを変更する権利を留保していることを意味します。代わりに、推奨される VARCHAR2 を使用してください。
Insert または Update のいずれかで起動するようにトリガーを変更します。 Insert のみで発火した場合、だれかがsupplier_nameを変更して、信頼されていないサプライヤを参照することができ、すべて問題ありません.