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

テーブル変更エラーを回避する方法

    簡単な答え-トリガーもミューティングもありません。

    Yowはpragma autonomous_transactionでトリガーを使用できます 特定の患者の残りの診断をカウントするために使用しますが、これを行う方法はお勧めしません。削除された診断にロジックを実装するための新しい関数または手順を作成することをお勧めします。このようなもの:

    create table Diagnosis as select 456 idDiseases, 123 di_patient from dual;
    /
    create table diagnosisCount as select 1 numDiseases, 123 di_patient from dual;
    /
    create table Patient as select 123 Pat_Person, 1 Pat_Sick from dual;
    /
    drop trigger di_patmustbewell;
    
    create or replace function deleteDiagnosis(idDiseases number) return number is
        rows_ number;
        di_patient number;
        Numdiseases number;
    begin
        <<del>> begin 
            delete Diagnosis where IdDiseases = deleteDiagnosis.IdDiseases
            returning Diagnosis.di_patient into deleteDiagnosis.di_patient
            ;
            rows_ := sql%rowcount;
            if rows_ != 1 then raise too_many_rows; end if;
        end del;
        select count(1) into deleteDiagnosis.numDiseases from Diagnosis where Di_Patient = deleteDiagnosis.di_patient;
        if deleteDiagnosis.numdiseases = 0 then <<upd>> begin 
            update Patient set Pat_Sick = 0 where Pat_Person = deleteDiagnosis.di_patient;
            exception when others then 
                dbms_output.put_line('Cannot update Patient di_patient='||di_patient);
                raise;
        end upd; end if;
        return rows_;
    end;
    /
    show errors
    
    declare rows_ number :=  deleteDiagnosis(456);
    begin dbms_output.put_line('deleted '||rows_||' rows'); end;
    /
    
    deleted 1 rows
    
    select * from Patient;
    PAT_PERSON   PAT_SICK
    ---------- ----------
           123          0
    

    アプリケーションでトリガーを使用することを希望する(または使用する必要がある)場合の代替ソリューション-トリガー本体で患者の診断の数を返す内部関数を宣言します:

    create or replace trigger di_patmustbewell
    after delete on diagnosis for each row
    declare
        numdiseases number;
        function getNumDiagnosis (di_patient number) return number is
            ret number;
            pragma autonomous_transaction;
        begin
            select count(1) into ret from diagnosis where di_patient = getNumDiagnosis.di_patient;
            return ret;
        end getNumDiagnosis;    
    begin
        numDiseases := getNumDiagnosis(:old.di_patient);
        if(numdiseases = 0) then
            update patient set pat_sick = 0 where pat_person = :old.di_patient;
        end if;
    end;
    /
    show errors;
    
    Trigger DI_PATMUSTBEWELL compiled
    

    少しお役に立てば幸いです。



    1. SQLServerのローカル一時テーブルとグローバル一時テーブルの違い

    2. Pythonのプロセス間でpostgresdbへの接続を共有する

    3. MySQLで1か月あたりの総売上高を計算する方法は?

    4. AWSEC2からAWSRDSへのOracleデータベースの移行、パート3