【发布时间】:2019-06-14 16:52:07
【问题描述】:
在我的数据库中有四个表:task、tasknotes、task_archive 和 tasknotes_archive。当一个条目从task 表复制到task_archive 表时,我想使用触发器来执行以下操作:
- 将
tasknotes表中的相关任务说明复制到tasknotes_archive表中。 - 删除我刚刚复制到
task_archive的task表中的条目 - 从
tasknotes中删除我刚刚复制到tasknotes_archive的条目
与数据库接口的应用程序是使用 JDBC 在 Java 中构建的。我可以通过对数据库的一系列调用或作为事务来实现上述结果。但是,使用初始插入语句似乎比将行从任务复制到 task_archive 触发其余事件更有效。我最初通过查看是否可以获得触发器来根据插入到 task_archive 中删除任务表中的条目来测试这一点。这似乎工作正常。但是,当我开始尝试添加脚本以使数据库从 tasknotes 复制到 tasknotes_archive 时,我收到错误消息,指出它在第一个 where 子句中无法识别 task_archive.task_id。重要的是,tasknotes 和 tasknotes_archive 具有完全相同的表结构,因此应该可以使用此插入方法,如该问题的答案中所述:MYSQL: How to copy an entire row from one table to another in mysql with the second table having one extra column?。然后,我尝试根据堆栈上其他问题的答案将其更改为 new.task_id。仍然收到错误消息。以下代码是task_archive中包含的插入触发器,我应该尝试开发它来对tasknotes_archive和task执行上述操作:
CREATE
TRIGGER `myDB`.`task_archive_AFTER_INSERT`
AFTER INSERT ON `myDB`.`task_archive`
FOR EACH ROW
BEGIN
INSERT INTO tasknotes_archive
SELECT tasknotes.* FROM tasknotes
WHERE tasknotes.task_id = task_archive.task_id;
DELETE FROM task
USING task, task_archive
WHERE task.task_id = task_archive.task_id;
END
我的问题是,是否可以按照所述将多个事件作为触发器运行?我是否正确假设这是一种更有效的执行方式,而不是在 java 中多次调用数据库?最后,写这个触发器的正确方法是什么?
【问题讨论】:
-
您正在复制从
tasknotes到tasknotes_archive的所有行,而不仅仅是与当前任务相关的行。 -
您的
DELETE语法完全错误。您需要使用JOIN,而不是USING。DELETE task, tasknotes FROM task JOIN tasknotes ON ... WHERE ... -
两个查询都需要一个使用
NEW.task_id的WHERE子句。查找与正在归档的当前行相关的行。 -
@Barmar 当删除之前的 INSERT 语句时,DELETE 语句本身可以正常工作。如果它有效,为什么它是错误的,或者更确切地说,为什么它是错误的方法?
-
啊,我看到
USING是DELETE中的替代语法。
标签: mysql database database-trigger