sql >> Database >  >> RDS >> Oracle

Oracle DBMS - Lees een tabel voor verwerking Updaten in een AFTER-trigger - tabel muteren

Ter verduidelijking:de muterende tabeluitzondering wordt gegenereerd omdat u probeert te lezen uit de rooms tabel in uw functie, niet omdat u probeert te lezen uit de properties tafel. Aangezien je een trigger op rijniveau hebt voor rooms , dat betekent dat de rooms table zich midden in een wijziging bevindt wanneer de trigger op rijniveau wordt geactiveerd en dat deze zich mogelijk in een inconsistente toestand bevindt. Oracle voorkomt dat u de rooms opvraagt tabel in die situatie omdat de resultaten niet noodzakelijk deterministisch of reproduceerbaar zijn.

Als u een trigger op instructieniveau hebt gemaakt (door het verwijderen van de FOR EACH ROW ) en je logica daar plaatst, zou je niet langer een muterende tabeluitzondering tegenkomen omdat de rooms tabel zou niet langer in een inconsistente staat zijn. Een trigger op instructieniveau kan echter niet zien welke rij(en) zijn gewijzigd. Dat zou betekenen dat u alle eigenschappen moet doorzoeken om te zien welke statuswaarden moeten worden aangepast. Dat zal niet bijzonder efficiënt zijn.

Ten koste van extra complexiteit kunt u de prestaties verbeteren door vast te leggen welke eigenschappen zijn gewijzigd in een trigger op rijniveau en daarnaar te verwijzen in een trigger op instructieniveau. Dat vereist over het algemeen drie triggers en een pakket, wat het aantal bewegende stukken duidelijk aanzienlijk verhoogt (als je op 11.2, je kunt een samengestelde trigger gebruiken met drie componententriggers, wat de zaken een beetje vereenvoudigt door de noodzaak om het pakket te gebruiken) . Dat zou er ongeveer zo uitzien

CREATE OR REPLACE PACKAGE trigger_collections
AS
  TYPE modified_property_tbl IS TABLE OF properties.property_id%type;
  g_modified_properties modified_property_tbl;
END;

-- Initialize the collection in a before statement trigger just in case
-- there were values there from a prior run
CREATE OR REPLACE TRIGGER trg_initialize_mod_prop_coll
  BEFORE INSERT OR UPDATE ON rooms
BEGIN
  trigger_collections.g_modified_properties := trigger_collections.modified_property_tbl();
END;

-- Put the property_id of the modified row in the collection
CREATE OR REPLACE TRIGGER trg_populate_mod_prop_coll
  AFTER INSERT OR UPDATE ON rooms
  FOR EACH ROW
BEGIN
  trigger_collections.g_modified_properties.extend();
  trigger_collections.g_modified_properties( trigger_collections.g_modified_properties.count + 1 ) := :new.property_id;
END;

CREATE OR REPLACE TRIGGER trg_process_mod_prop_coll
  AFTER INSERT OR UPDATE ON rooms
BEGIN
  FOR p IN 1 .. trigger_collections.g_modified_properties.count
  LOOP
    IF prop_vacancy_query( trigger_collections.g_modified_properties(i) ) = 0 
    THEN
      ...
END;



  1. Gegevens in Postgresql invoegen met dubbele waarden

  2. SQL Server Profiler gebruiken | Problemen met SQL Server-prestaties oplossen -5

  3. MySQL-query doorgeven via Javascript

  4. mysql indien niet aanwezig