sql >> データベース >  >> RDS >> Oracle

別のテーブルの列を検証する PL/SQL 行トリガーを作成する方法

    トリガーにはいくつかの問題があります。 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を変更して、信頼されていないサプライヤを参照することができ、すべて問題ありません.



    1. MariaDBでのMAKETIME()のしくみ

    2. OracleのNLS_CHARSET_NAME()関数

    3. 集計関数AVGを使用してレコードをフィルタリングする方法

    4. UbuntuにSQLiteとSQLiteブラウザをインストールする方法