oracle中单个事务中不同DML查询的不同时间戳

时间:2013-06-19 12:34:11

标签: sql oracle commit dml

我正在单个事务中对表执行插入和删除操作。我在此表上有触发器来更新日志。日志的主键为sequenceId,插入时总是递增。我先删除然后插入在交易中。

我有两个问题:

  • 插入和删除日志中的时间戳相同。我能否强迫它与众不同。
  • 日志中的操作顺序(插入/删除)正在反转。它显示了插入操作后的删除操作(根据sequenceId)。如何确保日志中的顺序一致(删除后插入)。

示例:

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;

如果我在单个事务中提交最后一个DML查询,那么我应该在address_log中看到相同的顺序。

1 个答案:

答案 0 :(得分:3)

时间戳列的数据类型是什么?

如果您使用具有足够精度的TIMESTAMP,则应保留该顺序。

例如TIMESTAMP(6)(精确到微秒) - 这是默认精度:

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
...

在任何情况下,如果你真的想要区分同时发生的事件(例如并发插入),你总是可以使用一个序列,并使用ORDER关键字来保证行的排序:

CREATE SEQUENCE log_sequence ORDER

这将允许您拥有可靠的排序顺序,即使事件是在同一时间发生的。