Как получить основной идентификатор обновленной строки и использовать его перед DML в триггере

Я заблокирован разработкой триггера 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 перед любой модификацией, чтобы его можно было легко откатить.

Есть ли другой способ, который я мог пропустить, чтобы справиться с этим делом?

заранее спасибо

Вы пробовали "прагма автономная_транзакция"? Это не 100% лекарство, но все же может пригодиться.

ekochergin 05.05.2022 11:48

Должен признаться, я даже не думал об этом в первую очередь. но ты прав. Я просто поместил это в свою вызываемую функцию, и это сработало как шарм. Спасибо

mmuss 05.05.2022 12:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решено добавлением прагмы Automotive_transaction в вызываемую функцию (PKG_TEMPLATE_MANAGEMENT.GET_TEMPLATE_XML).

Еще раз спасибо @ekochergin

Как сейчас написано, ваш ответ неясен. Пожалуйста, редактировать, чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.

Community 09.05.2022 03:25

Другие вопросы по теме