Frage

I am doing an insert and delete operation on a table in single transaction.I have trigger on this table which update the log.The log has primary key as sequenceId which always gets incremented on insertion.I do delete first and then insert in the transaction.

I have two issues :

  • The timestamp in the log for the insert and delete is being same. Can I force it to be different.
  • The order of operation(insert/delete) in the log is getting reversed. It shows delete operation coming after insert operation(according to sequenceId).How can I ensure that the order is consistent in the log(insert after delete).

Example :

create table address (ID number, COUNTRY char(2));

create table address_log(SEQ_ID number, ID number, COUNTRY char(2), DML_TYPE char(1), CHANGE_DATE timestamp(6));

create sequence seq_id start with 1 increment by 100 nominvalue nomaxvalue cache 20 noorder;

create or replace trigger trg_add
before insert or delete on address
FOR EACH ROW
BEGIN
if inserting then
  insert into address_log values(SEQ_ID.nextval, :new.ID, :new.COUNTRY, 'I', sysdate);
else
  insert into address_log values(SEQ_ID.nextval, :old.ID, :old.COUNTRY, 'D', sysdate);
end if;
end;

insert into address values(1,'US');
insert into address values(2,'CA');
delete from address where id = 1;
insert into address values(3,'UK');
delete from address where id = 3;

if I commit last DML queries in single transaction, then I should see the same order in address_log.

War es hilfreich?

Lösung

What is the datatype of your timestamp column?

If you use TIMESTAMP with a large enough precision, the order should be preserved.

For example TIMESTAMP(6) (precision to the micro-second) -- which is the default precision:

SQL> CREATE TABLE t_data (ID NUMBER, d VARCHAR2(30));

Table created

SQL> CREATE TABLE t_log (ts TIMESTAMP (6), ID NUMBER, action VARCHAR2(1));

Table created

SQL> CREATE OR REPLACE TRIGGER trg
  2     BEFORE INSERT ON t_data
  3     FOR EACH ROW
  4  BEGIN
  5     INSERT INTO t_log VALUES (systimestamp, :NEW.id, 'I');
  6  END;
  7  /

Trigger created

SQL> INSERT INTO t_data (SELECT ROWNUM, 'x' FROM dual CONNECT BY LEVEL <= 10);

10 rows inserted

SQL> SELECT * FROM t_log ORDER BY ts;

TS                                    ID ACTION
----------------------------- ---------- ------
19/06/13 15:47:51,686192               1 I
19/06/13 15:47:51,686481               2 I
19/06/13 15:47:51,686595               3 I
19/06/13 15:47:51,686699               4 I
19/06/13 15:47:51,686800               5 I
19/06/13 15:47:51,686901               6 I
...

In any case, if you really want to distinguish simultaneous events (concurrent inserts for instance), you can always use a sequence in addition, with the ORDER keyword to guarantee that the rows will be ordered:

CREATE SEQUENCE log_sequence ORDER

This would allow you to have a reliable sort order, even though the events took place at the same time.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top