HSQLDB 删除触发器在子查询中引起问题

问题描述

我在 HsqlDB 删除触发器中遇到问题,不知何故它没有按预期工作。

我正在尝试实现数据库中每次更改的日志。

对于示例测试,我执行这些 sql 语句:

CREATE TABLE msg (
  id INTEGER IDENTITY PRIMARY KEY,name VARCHAR(80)
);

CREATE TABLE log (
    id INTEGER IDENTITY PRIMARY KEY,row_id INTEGER,op VARCHAR(30),status VARCHAR(30)
);

insert into msg (id,name) values (0,'First Test Message');
insert into log (id,row_id,op,status) values (0,'insert','pending');

update log set status = 'done' where id = 0;

现在,我创建一个删除触发器并从 msg 表中删除行:

CREATE TRIGGER update_log_delete_msg
AFTER DELETE ON msg REFERENCING OLD ROW AS old_row FOR EACH ROW
BEGIN ATOMIC
    INSERT INTO log(row_id,status)
    SELECT old_row.id,'delete',CASE status WHEN 'pending' THEN 'cancel' ELSE 'pending' END FROM log
    WHERE row_id = old_row.id AND NOT status = 'cancel' ORDER BY id DESC LIMIT 1;

    UPDATE log SET status = 'cancel'
    WHERE row_id = old_row.id AND op = 'insert' AND status = 'pending';
END

delete from msg where id = 0;

到目前为止,它按预期工作:

insert into msg values (0,'Test Message Again');
insert into log (row_id,'pending');

这个,时间删除会出问题:

delete from msg where id = 0;

日志中状态的预期行为应该是 cancel 而不是 pending,为什么会导致问题?

解决方法

如果您不重复使用 ID 值零,这似乎有效。重复使用该值时,log 表中的旧行会导致意外结果。

insert into msg values (1,'Test Message Again');
insert into log (row_id,op,status) values (1,'insert','pending');
delete from msg where id = 1;                                        

-- dump of the log table

0,insert,done
1,delete,pending
2,1,cancel
3,cancel