我们的系统中有一个表可以从数字列中受益,因此我们可以轻松获取作业的第1,第2,第3条记录。当然,我们可以从应用程序本身更新此列,但我希望在数据库中进行此操作。
最终方法必须处理用户插入属于结果“中间”的数据的情况,因为它们可能无序地接收信息。他们也可以编辑或删除记录,因此会有相应的更新和删除触发器。
表格:
CREATE TABLE `test` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`seq` int(11) unsigned NOT NULL,
`job_no` varchar(20) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
以及一些示例数据:
mysql> SELECT * FROM test ORDER BY job_no, seq;
+----+-----+--------+------------+
| id | seq | job_no | date |
+----+-----+--------+------------+
| 5 | 1 | 123 | 2009-10-05 |
| 6 | 2 | 123 | 2009-10-01 |
| 4 | 1 | 123456 | 2009-11-02 |
| 3 | 2 | 123456 | 2009-11-10 |
| 2 | 3 | 123456 | 2009-11-19 |
+----+-----+--------+------------+
我希望从装配工更新“seq”列,但MySQL不允许这样做,并且在存储的函数/触发器中出现错误“无法更新表'test',因为它已被语句使用它调用了这个存储的函数/触发器“。
我的测试触发器如下:
CREATE TRIGGER `test_after_ins_tr` AFTER INSERT ON `test`
FOR EACH ROW
BEGIN
SET @seq = 0;
UPDATE
`test` t
SET
t.`seq` = @seq := (SELECT @seq + 1)
WHERE
t.`job_no` = NEW.`job_no`
ORDER BY
t.`date`;
END;
除了记得在每次更新这个表后调用函数之外,还有什么方法可以实现我的目标吗?
答案 0 :(得分:1)
这个怎么样?
CREATE TRIGGER `test_after_ins_tr` BEFORE INSERT ON `test`
FOR EACH ROW
BEGIN
SET @seq = (SELECT COALESCE(MAX(seq),0) + 1 FROM test t WHERE t.job_no = NEW.job_no);
SET NEW.seq = @seq;
END;
答案 1 :(得分:1)
来自Sergi上面的评论:
http://dev.mysql.com/doc/refman/5.1/en/stored-program-restrictions.html - “在存储的函数或触发器中,不允许通过调用函数或触发器的语句修改已经在使用(用于读取或写入)的表。”