Проблема с триггером для архивирования - PullRequest
0 голосов
/ 20 апреля 2019

Попытка создать триггер, который помещает данные в архивную таблицу, когда столбец с именем COMPLETION_STATUS переходит от неполного к завершенному, dbms является заполнителем для вставки, но я получаю следующие ошибки в операторе if

Ошибка (6,1): PLS-00103: При обнаружении символа введите здесь код "SELECT", когда ожидается одно из следующего: начало функция прагма тип процедуры подтип текущий курсор удаление ранее существующего символа "начало"был заменен на «SELECT» для продолжения.

Ошибка (9,1): PLS-00103: Обнаружен символ «IF» при ожидании одного из следующих действий: * & - +;/ at для остатка мода rem и / или группа, имеющая пересечение минус порядка начала объединения, где connect ||мультимножество символа ";"был заменен на «IF» для продолжения.

Ошибка (13,4): PLS-00103: Обнаружен символ «конец файла» при ожидании одного из следующих действий: (в начале регистра объявляется завершение исключения конца для goto, если цикл mod null прагма поднять возвратвыберите обновление, пока нажмете << продолжить, закрыть текущую, удалить блокировку извлечения, вставить открытую точку сохранения, откат, установить sql, выполнить коммит для очистки канала слияния </p>

Код:

create or replace TRIGGER ARCHIVING_TRIG 
BEFORE UPDATE OF COMPLETION_STATUS ON PROJECT_DATA

BEGIN
DECLARE COMPLETION_STATUS1 VARCHAR2(9);
SELECT COMPLETION_STATUS into COMPLETION_STATUS1
FROM PROJECT_DATA WHERE COMPLETION_STATUS = 'complete'

IF COMPLETION_STATUS1 = 'complete'
THEN 
DBMS.output('123');
END IF;
END;

Ответы [ 2 ]

1 голос
/ 20 апреля 2019
  • Блок DECLARE должен быть перед блоком BEGIN.
  • Оператор SELECT ... должен заканчиваться точкой с запятой (;).
  • Это dbms_output.put_line(), а не dbms.output();
  • Вы пытаетесь присвоить результат запроса, который потенциально может возвратить более одной строки скалярной переменной.
  • Строки, выбранные из project_data, не имеют отношения к тому, который (-ы) сработал.

Я предлагаю вам использовать что-то вроде:

CREATE TRIGGER archiving_trig
               AFTER UPDATE
                     ON project_data
               FOR EACH ROW
               WHEN (old.completion_status <> 'complete'
                     AND new.completion_status = 'complete')
BEGIN
  dbms_output.put_line('Trigger fired for ID ' || :new.id);
END;

дб <> скрипка

  • Я думаю, что AFTER - лучшее время, потому что вы хотите заархивировать строку после успешного изменения статуса.
  • Из-за WHEN триггер сработает, только если completion_status было изменено с чего-то, отличного от 'complete' на 'complete'. Но вам также может понадобиться способ удаления записей из архива, когда статус меняется с 'complete' на что-то другое. Это не рассматривается здесь.
  • Объявив его как FOR EACH ROW, вы получите доступ к значениям обновленной строки через :new. Таким образом, вам не нужен запрос для выбора ни этой переменной, ни для выбора.
0 голосов
/ 20 апреля 2019

Я думаю, вам нужно это:

create table PROJECT_DATA_NEW as select * from PROJECT_DATA where 1=2;


CREATE OR REPLACE TRIGGER ARCHIVING_TRIG 
AFTER UPDATE
   ON PROJECT_DATA
   FOR EACH ROW

DECLARE
status number;
BEGIN
status:=0;
select 1 into status from PROJECT_DATA where 
:new.COMPLETION_STATUS='complete' and 
:old.COMPLETION_STATUS='incomplete'

if (status=1) then
insert into PROJECT_DATA_NEW values(:old.column1,
:old.column2,
:old.column3,
:old.column4,
:old.column5,....etc); 
end if;
END;

/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...