Oracle
 sql >> база данни >  >> RDS >> Oracle

Oracle DBMS - Прочетете таблица преди обработка Актуализиране в тригер СЛЕД - променяща се таблица

Само за пояснение, изключението на променящата се таблица се хвърля, защото се опитвате да четете от rooms таблица във вашата функция, а не защото се опитвате да четете от properties маса. Тъй като имате тригер на ниво ред на rooms , това означава, че rooms таблицата е в средата на промяна, когато тригерът на ниво ред се задейства и че може да е в непоследователно състояние. Oracle ви пречи да правите запитвания към rooms таблица в тази ситуация, защото резултатите не са непременно детерминистични или възпроизводими.

Ако сте създали тригер на ниво изявление (премахване на FOR EACH ROW ) и поставете логиката си там, вече няма да срещнете изключение на променяща се таблица, защото rooms таблицата вече няма да бъде в непоследователно състояние. Тригерът на ниво изявление обаче не може да види кой ред(ове) е бил променен. Това би означавало, че ще трябва да разгледате всички свойства, за да видите кои стойности на състоянието трябва да бъдат коригирани. Това няма да е особено ефективно.

С цената на допълнителна сложност можете да подобрите производителността, като заснемете кои свойства са променени в тригер на ниво ред и след това се позовавате на това в тригер на ниво израз. Това обикновено изисква три тригера и пакет, което очевидно значително увеличава броя на движещите се части (ако сте на 11.2, можете да използвате комбиниран тригер с три компонентни тригера, което малко опростява нещата, като елиминира необходимостта от използване на пакета) . Това би изглеждало нещо като

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. В Oracle, по отношение на синтаксиса - как да преобразувам (+) синтаксиса в модерен конвенционален JOIN?

  2. Най-чистият начин за изграждане на SQL низ в Java

  3. Получаване на грешка - ORA-01858:беше намерен нецифров знак, където се очакваше число

  4. Комбиниране на 2 блока if и създаване на единична заявка

  5. Агентът е блокиран