Я заблокирован разработкой триггера Oracle (11g). Целью триггера является сохранение некоторых данных в таблице журнала аудита. Одно из полей, которые заполняются в этой таблице, представляет собой блок XML, сгенерированный функцией в пакете. Эта функция имеет 1 аргумент: ID строки, которую нужно обновить/удалить.
Поэтому я сначала написал этот триггер:
CREATE OR REPLACE TRIGGER TRG_TEMPLATE_FORMAT
BEFORE UPDATE OR DELETE
ON TEMPLATE_FORMAT
FOR EACH ROW
DECLARE
v_TEMPLATE_XML CLOB;
v_TEMPLATE_NAME VARCHAR2(128);
v_TEMPLATE_FULL_NAME VARCHAR2(128);
BEGIN
IF UPDATING THEN
SELECT TEMPLATE_NAME INTO v_TEMPLATE_NAME FROM TEMPLATES WHERE TEMPLATE_ID =: OLD.TEMPLATE_ID;
SELECT TEMPLATE_FULL_NAME INTO v_TEMPLATE_FULL_NAME FROM TEMPLATES WHERE TEMPLATE_ID = :OLD.TEMPLATE_ID;
v_TEMPLATE_XML := PKG_TEMPLATE_MANAGEMENT.GET_TEMPLATE_XML(:OLD.TEMPLATE_ID);
INSERT INTO TEMPLATES_BACK(
TEMPLATE_ID,
TEMPLATE_FULL_NAME,
TEMPLATE_NAME,
EVENT_TYPE,
EVENT_TIMESTAMP,
OLD_XML_TEMPLATE_SOURCE
)
VALUES(
:OLD.TEMPLATE_ID,
v_TEMPLATE_FULL_NAME,
v_TEMPLATE_NAME,
'UPDATE ON TEMPLATE_FORMAT',
SYSDATE,
v_TEMPLATE_XML
);
ELSIF DELETING THEN
SELECT TEMPLATE_NAME INTO v_TEMPLATE_NAME FROM TEMPLATES WHERE TEMPLATE_ID = :OLD.TEMPLATE_ID;
SELECT TEMPLATE_FULL_NAME INTO v_TEMPLATE_FULL_NAME FROM TEMPLATES WHERE TEMPLATE_ID = :OLD.TEMPLATE_ID;
v_TEMPLATE_XML := PKG_TEMPLATE_MANAGEMENT.GET_TEMPLATE_XML(:OLD.TEMPLATE_ID);
INSERT INTO TEMPLATES_BACK(
TEMPLATE_ID,
TEMPLATE_FULL_NAME,
TEMPLATE_NAME,
EVENT_TYPE,
EVENT_TIMESTAMP,
OLD_XML_TEMPLATE_SOURCE
)
VALUES(
:OLD.TEMPLATE_ID,
v_TEMPLATE_FULL_NAME,
v_TEMPLATE_NAME,
'DELETE FROM TEMPLATE_FORMAT',
SYSDATE,
v_TEMPLATE_XML
);
END IF;
END;
/
Поскольку таблица TEMPLATE_FORMAT используется в функции GET_TEMPLATE_XML(), конечно, я получаю старую "хорошую" ошибку "Таблица мутирует"...
Я подумал об использовании составного триггера после небольшого поиска и вызвал свою функцию в блоке BEFORE STATEMENT. Проблема в том, что привязки :OLD / :NEW нельзя использовать в этом блоке.
Конечная цель этого XML — зафиксировать значения нескольких записей в этом XML перед любой модификацией, чтобы его можно было легко откатить.
Есть ли другой способ, который я мог пропустить, чтобы справиться с этим делом?
заранее спасибо
Должен признаться, я даже не думал об этом в первую очередь. но ты прав. Я просто поместил это в свою вызываемую функцию, и это сработало как шарм. Спасибо
Решено добавлением прагмы Automotive_transaction в вызываемую функцию (PKG_TEMPLATE_MANAGEMENT.GET_TEMPLATE_XML).
Еще раз спасибо @ekochergin
Как сейчас написано, ваш ответ неясен. Пожалуйста, редактировать, чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.
Вы пробовали "прагма автономная_транзакция"? Это не 100% лекарство, но все же может пригодиться.