将行从一个 table 复制到另一个,由第 3 个 table 插入触发

copy rows from one table to another triggered by insert on a 3rd table

在我的数据库中有四个 table:tasktasknotestask_archivetasknotes_archive。当条目从 task table 复制到 task_archive table 我想使用触发器执行以下操作:

  1. 将相关任务笔记从tasknotestable复制到tasknotes_archivetable。
  2. 删除task中的条目table我刚刚复制到task_archive
  3. tasknotes 中删除我刚刚复制到 tasknotes_archive
  4. 的条目

与数据库交互的应用程序是使用 JDBC 在 Java 中构建的。我可以通过对数据库的一系列调用或作为事务来实现上述结果。但是,使用初始插入语句似乎比将行从任务复制到 task_archive 触发其余事件更有效。我最初通过查看是否可以获得触发器来根据插入 task_archive 从任务 table 中删除条目来对此进行测试。这似乎工作正常。但是,当我开始尝试在脚本中添加以使数据库从 tasknotes 复制到 tasknotes_archive 时,我收到错误消息,指出它无法识别第一个 where 子句中的 task_archive.task_id。重要的是,tasknotes 和 tasknotes_archive 具有完全相同的 table 结构,所以这个插入方法应该是可行的,正如这个问题的答案中所讨论的: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 和任务:

上执行上述操作
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 中多次调用数据库的更有效方法?最后,这个触发器的正确​​写法是什么?

您需要使用NEW.task_id获取与触发器当前行相关的任务。

如果您使用 CLI 执行此操作,则需要 DELIMITER 语句,以便触发器中的语句之间可以有 ;

DELIMITER $$

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 = NEW.task_id;

    DELETE task, tasknotes
    FROM task JOIN tasknotes USING (task_id)
    WHERE task.task_id = NEW.task_id;
END
$$
DELIMITER ;