是否可以从MySQL中的触发器中更新“订单”列?

时间:2009-11-19 13:02:23

标签: sql mysql

我们的系统中有一个表可以从数字列中受益,因此我们可以轻松获取作业的第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;

除了记得在每次更新这个表后调用函数之外,还有什么方法可以实现我的目标吗?

2 个答案:

答案 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 - “在存储的函数或触发器中,不允许通过调用函数或触发器的语句修改已经在使用(用于读取或写入)的表。”