Я пишу общий триггер оракула. Предположим, что есть много основных таблиц, таких как PERSON_INFO, EMPLOYEE_INFO и т. Д., И соответствующие им таблицы аудита, такие как PERSON_INFO_AUDIT, EMPLOYEE_INFO_AUDIT. Структура приведена ниже.
PERSON_INFO имеет столбцы: -
------------------------------------------------
| PERSON_INFO |
------------------------------------------------
| PERSON_ID | FIRST_NAME | LAST_NAME |
| (NUMBER) | (VARCHAR2) | (VARCHAR2)|
------------------------------------------------
| 1 | Andrew | Jack |
------------------------------------------------
PERSON_INFO_AUDIT содержит все столбцы PERSON_INFO вместе с двумя дополнительными столбцамиOPERATIONS и AUDIT_DATE.
Требование заключается в том, что если обновляется какая-либо из основных таблиц или удаляется какая-либо строка из основной таблицы, то старые записи основной таблицы должны быть вставлены в соответствующую таблицу аудита.
и затем я пишу обновление, например: -
ОБНОВЛЕНИЕ PERSON_INFO SET FIRST_NAME = 'John';
затем старые значения для PERSON_INFO должен быть вставлен в PERSON_INFO_AUDIT Таблица, подобная приведенной ниже: -
PERSON_INFO_AUDIT должна теперь содержать: -
-------------------------------------------------------------------------
| PERSON_INFO_AUDIT |
-------------------------------------------------------------------------
| PERSON_ID | FIRST_NAME | LAST_NAME | AUDIT_DATE | OPERATIONS|
| (NUMBER) | (VARCHAR2) | (VARCHAR2)| (TIMESTAMP) | (CHAR) |
-------------------------------------------------------------------------
| 1 | Andrew | Jack | 30-08-2019 | U |
-------------------------------------------------------------------------
Здесь Audit_date:сегодняшняя дата и операции указывают, были ли удалены строки в главной таблице (D) или обновлены (U). Чтобы облегчить описанный выше сценарий, я написал следующую триггерную функцию.
CREATE OR replace TRIGGER trig_PERSON_INFO_deleteupdate
after UPDATE OR DELETE
ON PERSON_INFO
FOR EACH ROW
DECLARE
base_table_name clob;
audit_table_name clob;
base_table_cols_in_string clob;
audit_table_cols_in_string clob;
operation char;
final_query clob;
BEGIN
base_table_name:= 'PERSON_INFO';
audit_table_name := base_table_name || '_AUDIT';
IF UPDATING THEN
operation:= 'U';
ELSE
operation:= 'D';
END IF;
SELECT LISTAGG(COLUMN_NAME, ',') WITHIN GROUP (ORDER BY column_id)
INTO base_table_cols_in_string
FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME= 'PERSON_INFO';
audit_table_cols_in_string:= base_table_cols_in_string || ',AUDIT_DATE,OPERATIONS';
final_query:= 'INSERT INTO ' || audit_table_name || '(' || audit_table_cols_in_string || ') VALUES(' || ':OLD.PERSON_ID,:OLD.FIRST_NAME,:OLD.LAST_NAME,' || SYSDATE || ',''' || operation || ''');';
dbms_output.put_line(final_query);
EXECUTE IMMEDIATE final_query;
END;
Сформирован запрос:
INSERT INTO PERSON_INFO_AUDIT(PERSON_ID,FIRST_NAME,LAST_NAME,AUDIT_DATE,OPERATIONS) VALUES(:OLD.PERSON_ID,:OLD.FIRST_NAME,:OLD.LAST_NAME,30-10-19,'U');
Однако, когда я пытаюсь выполнить запрос с помощью EXECUTE IMMEDIATE final_query, тогда я получаю ошибку