Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Oracle DBMS — Odczytaj tabelę przed przetwarzaniem Aktualizacja w wyzwalaczu PO — tabela mutująca

Dla wyjaśnienia, wyjątek tabeli mutacji jest zgłaszany, ponieważ próbujesz czytać z rooms tabeli w Twojej funkcji, nie dlatego, że próbujesz czytać z properties stół. Ponieważ masz wyzwalacz na poziomie wiersza w rooms , oznacza to, że rooms tabela znajduje się w trakcie zmiany, gdy wyzwalany jest wyzwalacz na poziomie wiersza i może być w niespójnym stanie. Oracle uniemożliwia odpytywanie rooms tabeli w tej sytuacji, ponieważ wyniki niekoniecznie są deterministyczne lub powtarzalne.

Jeśli utworzyłeś wyzwalacz na poziomie instrukcji (usuwając FOR EACH ROW ) i umieść tam swoją logikę, nie napotkasz już wyjątku tabeli mutacji, ponieważ rooms tabela nie byłaby już w niespójnym stanie. Jednak wyzwalacz na poziomie instrukcji nie jest w stanie zobaczyć, które wiersze zostały zmodyfikowane. Oznaczałoby to, że musisz przejrzeć wszystkie właściwości, aby zobaczyć, które wartości stanu należy dostosować. To nie będzie szczególnie wydajne.

Kosztem dodatkowej złożoności można poprawić wydajność, przechwytując, które właściwości zmieniły się w wyzwalaczu na poziomie wiersza, a następnie odwołując się do tego w wyzwalaczu na poziomie instrukcji. Zwykle wymaga to trzech wyzwalaczy i pakietu, co oczywiście znacznie zwiększa liczbę ruchomych elementów (jeśli korzystasz z 11.2, możesz użyć złożonego wyzwalacza z trzema wyzwalaczami składowymi, co nieco upraszcza sprawę, eliminując potrzebę korzystania z pakietu) . To wyglądałoby mniej więcej tak

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL*Plus jak zaakceptować zmienną tekstową z monitu?

  2. Jak znaleźć nazwę wiązania w Oracle?

  3. Oracle SQL, uzupełnij brakującą wartość najbliższym brakiem

  4. Aktualizuj zduplikowane wiersze tylko za pomocą funkcji MAX w SQL

  5. Wybierz z połączonego widoku, a konkatenacja nie działa?