我正在单个事务中对表执行插入和删除操作。我在此表上有触发器来更新日志。日志的主键为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中看到相同的顺序。
答案 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
这将允许您拥有可靠的排序顺序,即使事件是在同一时间发生的。