问题描述
我在 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;
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