Триггеры Oracle не вставляют последние записи в таблицы

У меня есть TABLE_1, которая является родительской таблицей этих записей, которая находится в SCHEMA_1 и заполняется из приложения JAVA / Node.js при транзакции. Также ниже есть триггер (SCHEMA_1.TRIGGER_CALL_SP_OF_SCHEMA_2) на том же SCHEMA_1 и вызов другой хранимой процедуры для заполнения другого TABLE_2, который находится в SCHEMA_2, на основе транзакций Table_1.

Курок:

create or replace trigger SCHEMA_1.TRIGGER_CALL_SP_OF_SCHEMA_2
  AFTER UPDATE OR INSERT OR DELETE ON SCHEMA_1.TABLE_1
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW
  DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    SCHEMA_2.SP_OF_SCHEMA_2(:NEW.RECORD_ID);
    commit;
  EXCEPTION   WHEN OTHERS THEN
    RAISE;
END;

Хранимая процедура:

create or replace PROCEDURE SCHEMA_2.SP_OF_SCHEMA_2(P_RECORD_ID NUMBER ) AS
BEGIN
    DELETE FROM SCHEMA_2.TABLE_2 WHERE RECORD_ID = P_RECORD_ID;           
    FOR rec IN (SELECT RECORD_ID, COL2, COL3, COL4  from SCHEMA_1.TABLE_1 where RECORD_ID = P_RECORD_ID)
    LOOP
         INSERT INTO SCHEMA_2.TABLE_2 (RECORD_ID, COL2, COL3, COL4) VALUES(rec.RECORD_ID, rec.COL2, rec.COL3,rec.COL4 );
   END LOOP;
 COMMIT;
END; 

Так что проблема в Table_2, где не всегда есть самые свежие записи. Например: когда первая запись_Id вставлена ​​в Table_1, но в Table_2 нет никакой записи. Когда второй раз с тем же идентификатором записей, вставленным с другими значениями в Таблице_1, но в Таблице_2, вставлен только последний идентификатор записи с данными. (Опять же, не последняя запись). Ниже приведены образцы записей: (Примечание - в обеих таблицах отсутствуют какие-либо ПК.)

Таблица 1

+------------+-------+----------+---------+
| RECORD_ID  |  COL2 |   COL3   |  COL4   |
+------------+-------+----------+---------+
|          1 |   101 | abc      |  insert |
+------------+-------+----------+---------+

Таблица 2

+------------+-------+----------+------+
| RECORD_ID  |  COL2 |   COL3   | COL4 |
+------------+-------+----------+------+

Таблица 1

+------------+-------+----------+---------+
| RECORD_ID  |  COL2 |   COL3   |  COL4   |
+------------+-------+----------+---------+
|          1 |   101 | abc      |  insert |
|          1 |   102 | xyz      |  insert |
+------------+-------+----------+---------+

Таблица 2

+------------+-------+----------+---------+
| RECORD_ID  |  COL2 |   COL3   |  COL4   |
+------------+-------+----------+---------+
|          1 |   101 | abc      |  insert |
+------------+-------+----------+---------+

Это b'cze какой-либо последовательности фиксации базы данных или каких-либо проблем, связанных с транзакциями, или любого другого возможного сценария? Как можно добиться этого, чтобы всегда обновлять Table_2. Заранее спасибо.


person Akshay    schedule 19.12.2019    source источник
comment
ваша процедура проходит через (SELECT RECORD_ID, COL2, COL3, COL4 из SCHEMA_1.TABLE_1, где RECORD_ID = P_RECORD_ID), вы уверены, что это вернет какое-либо значение?   -  person damir huselja    schedule 19.12.2019
comment
ни в триггере, ни в процедуре не используйте commit. Это может быть излишним для целостности транзакции.   -  person Barbaros Özhan    schedule 19.12.2019


Ответы (1)


Триггер имеет автономную транзакцию.

Таким образом, вставка / обновление / удаление, запускающая триггер, находится в отдельной транзакции от вызова процедуры в триггере.

Транзакции могут просматривать только зафиксированные изменения, внесенные другими.

Таким образом, транзакция в триггере не может видеть вставленную вами строку!

create table t1 (
  c1 int
);
create table t2 (
  c1 int
);

create or replace trigger trig
after insert on t1
for each row
declare
  pragma autonomous_transaction;
begin
  insert into t2
    select * from t1
    where  c1 = :new.c1;

  dbms_output.put_line ( 'Rows added: ' || sql%rowcount );
  commit;
end;
/

insert into t1 values ( 1 );

Rows added: 0
commit;
insert into t1 values ( 1 );

Rows added: 1

select * from t2;

        C1
----------
         1

Поскольку обращение к table_1 без автономной транзакции вызовет ошибку мутирующего триггера (ORA-04091), вам необходимо переосмыслить этот процесс.

person Chris Saxon    schedule 19.12.2019