sql >> Database >  >> RDS >> Oracle

Hoe u fouten bij het muteren van tabellen kunt voorkomen

Kort antwoord - geen trigger, geen mutatie.

U kunt de trigger gebruiken met pragma autonomous_transaction voor het tellen van resterende diagnoses voor bepaalde patiënten, maar het is niet de aanbevolen manier om dit te doen. Het is beter om een ​​nieuwe functie of procedure te creëren om uw logica te implementeren bij verwijderde diagnoses. Zoiets als dit:

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

Een alternatieve oplossing, als u de voorkeur geeft (of moet) om een ​​trigger in uw toepassing te gebruiken - declareer de interne functie die de telling van de diagnoses van de patiënt in de triggerbody retourneert:

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

Ik hoop dat het je een beetje helpt.



  1. Gedrag van NOT LIKE met NULL-waarden

  2. Overwegingen met betrekking tot gegevensintegriteit en prestatie in semisynchrone MySQL-replicatie

  3. Hoe gebruik ik lentegegevens jpa om de jsonb-kolom op te vragen?

  4. Hoe COUNT(*) prestaties op InnoDB te optimaliseren met behulp van index