Это действительно не та вещь, которую мы должны делать в триггере. Есть некоторая сложная обработка, которой сложно управлять. Например, что должно произойти, если вы не можете создать триггер? Или если усечение не получится?
Это усугубляется запретом на выдачу коммитов в триггерах. Все операторы DDL выдают коммиты (по два на оператор), поэтому единственный способ запустить операторы DDL из триггера - использовать прагму autonomous_transaction
. Это вложенная транзакция, что означает, что она не может видеть текущее содержимое таблицы. Так что все это немного грязно.
Вот мысленный эксперимент, который иллюстрирует, что вам нужно сделать:
create or replace trigger replicate_pdu_table
after insert on pdu
declare
-- note use the twenty-hour clock in mask
v_tablename varchar2(30) := 'PDU_IN_PROGRESS_' || to_char(sysdate, 'YYYYMMDDHH24MISS');
procedure create_table is
pragma autonomous_transaction;
begin
execute immediate 'create table ' || v_tablename || ' as select * from pdu where 1=2';
end create_table;
procedure truncate_pdu is
pragma autonomous_transaction;
begin
execute immediate 'truncate table pdu';
end truncate_pdu;
begin
create_table;
execute immediate 'insert into ' || v_tablename || ' select * from pdu';
truncate_pdu;
end;
/
Проблема в укорочении: швыряет
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
Причина в том, что триггер срабатывает, когда мы вставляем строки в pdu
. То есть, прежде чем мы сможем выдать коммит. Следовательно, основной сеанс имеет блокировку pdu
, поэтому автономная транзакция не может выполнять усечение. Это является абсолютным препятствием для использования триггера: вам нужно запустить его как процедуру, возможно, вызванную из задания опроса или из очереди.
Более широкий вопрос: зачем ты это делаешь? Транзакционный подход, который создает таблицы на лету - это всегда запах . Помимо распространения небольшого количества загроможденных схем, есть риски провала, о которых я упоминал во вступлении. Кроме того, как процессы, использующие созданную таблицу, узнают ее имя ???? Весь ваш процесс будет построен из динамического SQL. Это кошмар обслуживания и поддержки.
Не зная деталей того, чего вы пытаетесь достичь, невозможно предложить лучший подход. Но будьте уверены, есть определенно лучшие подходы для вас.