我正试着跟踪数据随时间的变化。我决定使用“id,revision”模式。请注意,这两个键字段都不是自动递增的-我使用before insert触发器来计算新行应该获得的id和修订。是的,我可以在应用程序端处理所有这些,但选择在数据库端处理。
DROP TABLE IF EXISTS person;
CREATE TABLE person (
id BIGINT(12) UNSIGNED NOT NULL,
revision BIGINT(12) UNSIGNED NOT NULL,
last_name varchar(30) NOT NULL,
first_name varchar(30) NOT NULL,
PRIMARY KEY ( id, revision)
);
DROP TABLE IF EXISTS person_debug;
CREATE TABLE person_debug (
id BIGINT(12) UNSIGNED NOT NULL,
revision BIGINT(12) UNSIGNED NOT NULL,
message varchar(40),
PRIMARY KEY ( id, revision)
);
DELIMITER $$
CREATE TRIGGER person_insert BEFORE INSERT ON person
FOR EACH ROW
BEGIN
DECLARE new_id BIGINT;
DECLARE new_revision BIGINT;
DECLARE row_cnt BIGINT;
IF( NEW.id IS NULL) THEN
SET new_id = 1;
SET new_revision = 0;
SET row_cnt = (SELECT TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_NAME = 'person' AND TABLE_TYPE = 'BASE TABLE');
IF( row_cnt > 0 ) THEN
SET new_id = (SELECT MAX( id) + 1 FROM person);
END IF;
ELSE
SET new_id = NEW.id;
SET new_revision = (SELECT MAX( revision) + 1 FROM person WHERE id = new_id);
INSERT INTO person_debug VALUES ( new_id, new_revision, "tried an update");
END IF;
SET NEW.id = new_id;
SET NEW.revision = new_revision;
END;
$$
DELIMITER ;
INSERT INTO person ( id, last_name, first_name) VALUES
( null, 'Hamilton', 'Mike'),
( null, 'Jefferson', 'Thomas'),
( null, 'Nixon', 'Richard'),
( null, 'Ford', 'Gerald'),
( null, 'Reagan', 'Ronald'),
( null, 'Lincoln', 'Abraham')
( null, 'Roosevelt', 'Teddy')
( null, 'Hayden', 'Rutherford')
;
INSERT INTO person ( id, last_name, first_name) VALUES
( 1, 'Hamilton', 'Alexis'),
( 8, 'Hays', 'Rutherford')
( 1, 'Hamilton', 'Alexander')
;
当我在mysql会话中手动运行脚本时,这一切都非常有效
source create_tables.sql
select * from person;
id| revision| last_name | first_name
====================================
1| 0| 'Hamilton' | 'Mike'
1| 1| 'Hamilton' | 'Alexis'
1| 2| 'Hamilton' | 'Alexander'
2| 0| 'Jefferson'| 'Thomas'
3| 0| 'Nixon' | 'Richard'
4| 0| 'Ford' | 'Gerald'
5| 0| 'Reagan' | 'Sylvester'
6| 0| 'Lincoln' | 'Abraham'
7| 0| 'Roosevelt'| 'Teddy'
8| 0| 'Hayden' | 'Rutherford'
8| 1| 'Hays' | 'Rutherford'
select * from person_debug;
id| revision| message
====================================
1| 1| 'tried an update'
1| 2| 'tried an update'
8| 1| 'tried an update'
好极了。触发器的所有部分都在执行,它们都完全按照预期工作。
现在我建立了一个java/springdata/mvc/mysql webapp,其中一个页面包含一个表,表中以行的形式包含person的内容,您可以选择一行,选择更新该行,然后填充一个弹出窗体,您可以编辑然后提交,然后返回控制器,控制器示例化一个新的person实体并将其发送到数据库。
问题是,当我尝试更新一个人时,原始行被更新,而没有插入新行。例如,提交带有5 | 0 |“reagan”|“ronald”的更新表单
应该导致
select * from person;
id| revision| last_name | first_name
====================================
1| 0| 'Hamilton' | 'Mike'
1| 1| 'Hamilton' | 'Alexis'
1| 2| 'Hamilton' | 'Alexander'
2| 0| 'Jefferson'| 'Thomas'
3| 0| 'Nixon' | 'Richard'
4| 0| 'Ford' | 'Gerald'
5| 0| 'Reagan' | 'Sylvester'
5| 1| 'Reagan' | 'Ronald'
6| 0| 'Lincoln' | 'Abraham'
7| 0| 'Roosevelt'| 'Teddy'
8| 0| 'Hayden' | 'Rutherford'
8| 1| 'Hays' | 'Rutherford'
select * from person_debug;
id| revision| message
====================================
1| 1| 'tried an update'
1| 2| 'tried an update'
5| 1| 'tried an update'
8| 1| 'tried an update'
但是我得到了
select * from person;
id| revision| last_name | first_name
====================================
1| 0| 'Hamilton' | 'Mike'
1| 1| 'Hamilton' | 'Alexis'
1| 2| 'Hamilton' | 'Alexander'
2| 0| 'Jefferson'| 'Thomas'
3| 0| 'Nixon' | 'Richard'
4| 0| 'Ford' | 'Gerald'
5| 0| 'Reagan' | 'Ronald'
6| 0| 'Lincoln' | 'Abraham'
7| 0| 'Roosevelt'| 'Teddy'
8| 0| 'Hayden' | 'Rutherford'
8| 1| 'Hays' | 'Rutherford'
select * from person_debug;
id| revision| message
====================================
1| 1| 'tried an update'
1| 2| 'tried an update'
8| 1| 'tried an update'
这就好像当一行从webapp通过jdbc连接进入时,要添加该行时触发器没有执行一样。
有什么想法吗?
蒂亚,
暗号战士
暂无答案!
目前还没有任何答案,快来回答吧!