Я имею AFTER INSERT OR UPDATE OR DELETE
триггер, который я пишу для хранения каждого рекордного пересмотра, который происходит в определенной таблице путем копирования INSERT
и UPDATE
:NEW
значения в зеркальную таблицу, и для DELETE
:OLD
значения.
Я мог значительно не создать помехи своему коду путем условной передачи любого :NEW
или :OLD
запись в процедуру, которая затем сделала бы вставку в мою таблицу истории. К сожалению, я, может казаться, не нахожу способ передать все :OLD
или :NEW
запись.
Я пропускаю что-то или не являюсь там никаким способом постараться не перечислять каждый :NEW
и :OLD
столбец, поскольку я вызываю свою процедуру вставки?
Я хочу сделать следующее:
DECLARE
PROCEDURE LOCAL_INSERT(historyRecord in ACCT.ACCOUNTS%ROWTYPE) IS
BEGIN
INSERT INTO ACCT.ACCOUNTS_HISTORY (ID, NAME, DESCRIPTION, DATE) VALUES (historyRecord.ID, historyRecord.NAME, historyRecord.DESCRIPTION, SYSDATE);
END;
BEGIN
IF INSERTING OR UPDATING THEN
LOCAL_INSERT(:NEW);
ELSE --DELETING
LOCAL_INSERT(:OLD);
END IF;
END;
Но я застреваю, делая это:
DECLARE
PROCEDURE LOCAL_INSERT(id in ACCT.ACCOUNTS.ID%TYPE,
name in ACCT.ACCOUNTS.NAME%TYPE,
description in ACCT.ACCOUNTS.DESCRIPTION%TYPE) IS
BEGIN
INSERT INTO ACCT.ACCOUNTS_HISTORY (ID, NAME, DESCRIPTION, DATE) VALUES (id, name, description, SYSDATE);
END;
BEGIN
IF INSERTING OR UPDATING THEN
LOCAL_INSERT(:NEW.ID, :NEW.NAME, :NEW.DESCRIPTION);
ELSE --DELETING
LOCAL_INSERT(:OLD.ID, :OLD.NAME, :OLD.DESCRIPTION);
END IF;
END;
Хорошо, таким образом, это не похоже на большую разницу, но это - просто пример с 3 столбцами, а не десятки.
Это не так. Вы должны сделать это сами посредством перечисления.
Причины, по которым он не может / не работает автоматически, включают:
: старый
и : новый
- соглашения по умолчанию; вы можете присвоить ссылкам : old
и : new
все, что захотите, с помощью предложения REFERENCING
оператора CREATE TRIGGER
.
вам потребуется публичное объявление типа (через CREATE TYPE
или через объявление пакета), чтобы иметь возможность использовать его в качестве аргумента для другого фрагмента кода.
код триггера - это интерпретируемый код, а не скомпилированный код.
Я не думаю, что такое возможно. Документация не упоминает ничего подобного.
Это, конечно, будет стоить производительности, но вы можете попробовать определить свой триггер AFTER INSERT
и другой BEFORE UPDATE OR DELETE
, и в триггере сделать что-то вроде:
SELECT *
INTO rowtype_variable
FROM accounts
WHERE accounts.id = :NEW.id; -- :OLD.id for UPDATE and DELETE
а затем вызвать свою процедуру с этой rowtype_variable
.