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

Oracle - Проблем при създаването на тригер, който актуализира друга таблица

Няколко въпроса без определен ред.

Първо, в тялото на тригер на ниво ред трябва да използвате :new и :old за справка с новите и старите записи. Водещото дебело черво е необходимо. Така че вашето WHERE клауза трябва да бъде

WHERE PROJECTID = :new.PROJECTID

Второ, ако изпълнявате своя CREATE TRIGGER в SQL*Plus можете да получите списък с грешки и предупреждения, като използвате SHOW ERRORS команда, т.е.

SQL> show errors

Можете също така да направите заявка за DBA_ERRORS таблица (или ALL_ERRORS или USER_ERRORS в зависимост от вашето ниво на привилегия), но това не е нещо, до което обикновено трябва да прибягвате.

Трето, ако приемем, че синтактичните грешки бъдат коригирани, ще получите мутиращ грешка в таблицата ако използвате тази логика. Тригер на ниво ред на таблица A (TPM_TRAININGPLAN в този случай) не може да направи запитване към таблица A, защото таблицата може да е в непоследователно състояние. Можете да заобиколите това, както Тим показва в статията си, като създадете пакет с колекция, инициализирате тази колекция в тригер преди израз, попълните данните в колекцията в тригер на ниво ред и след това обработите модифицираните редове в тригер след изявление. Това обаче е прилично количество сложност, което да добавите към системата, тъй като ще трябва да управлявате множество различни обекти.

Като цяло би било по-добре да внедрите тази логика като част от какъвто и да е API, който използвате за манипулиране на TPM_TRAININGPLAN маса. Ако това е съхранена процедура, има много по-голям смисъл да поставите логиката за актуализиране на TPM_PROJECT в тази съхранена процедура, вместо да я поставите в тригер. Известно е, че е болезнено да се опитвате да отстранявате грешки в приложение, което има много логика, вградена в тригери, защото това прави много трудно за разработчиците да следват точно какви операции се изпълняват. Като алтернатива можете да премахнете TRAININGDELIVERYSTART колона от TPM_PROJECT таблица и просто изчислете минималната начална дата по време на изпълнение.

Четвърто, ако вашият тригер се задейства при вмъквания, актуализации и изтривания, не можете просто да посочите :new стойности. :new е валиден за вмъквания и актуализации, но ще бъде NULL, ако правите изтриване. :old е валиден за изтривания и актуализации, но ще бъде NULL, ако правите вмъкване. Това означава, че вероятно трябва да имате логика по линия на (позовавайки се на пакетното решение на Тим)

BEGIN
  IF inserting 
  THEN
    trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
  ELSIF updating
  THEN
    trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
  ELSIF deleting
  THEN
    trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
  END IF;
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 SQL - Как да получите отделни редове с помощта на аналитична функция RANK() или DENSE_RANK() или ROW_NUMBER()?

  2. Грешка на Oracle:[:в:неизвестен оператор

  3. BEGIN/END и CREATE Таблица в един .sql файл

  4. Проблем с Django inspectdb при използване на база данни на Oracle

  5. Как мога да се свържа с Oracle в ADO.NET Entity Data Model