скопировать строки из одной таблицы в другую, вызванные вставкой в ​​3-ю таблицу - PullRequest
0 голосов
/ 21 января 2019

В моей базе данных есть четыре таблицы: task, tasknotes, task_archive и tasknotes_archive. Когда запись копируется из таблицы task в таблицу task_archive, я хочу использовать триггер для выполнения следующего:

  1. скопировать примечания к соответствующей задаче из таблицы tasknotes в таблицу tasknotes_archive.
  2. удалить запись в таблице task, которую я только что скопировал в task_archive
  3. удалить записи из tasknotes, которые я только что скопировал в tasknotes_archive

Приложение, которое взаимодействует с базой данных, построено на Java с использованием JDBC. Я мог бы достичь вышеупомянутых результатов как в виде серии обращений к базе данных, так и в виде транзакции. Однако может показаться более эффективным иметь начальный оператор вставки, чем копировать строку из задачи в task_archive, вызывая остальные события. Сначала я проверил это, посмотрев, смогу ли я получить триггер для удаления записи из таблицы задач на основе вставки в task_archive. Казалось, это работает нормально. Однако, когда я начал пытаться добавить сценарий, чтобы заставить БД копировать из tasknotes в tasknotes_archive, я получил сообщения об ошибке, в которых говорилось, что она не распознает task_archive.task_id в первом предложении where. Важно отметить, что tasknotes и tasknotes_archive имеют одинаковую структуру таблицы, поэтому этот метод вставки должен быть возможен, как обсуждалось в ответе на этот вопрос: MYSQL: как скопировать всю строку из одной таблицы в другую в mysql, когда вторая таблица имеет один дополнительный столбец? . Затем я попытался изменить это на 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? Наконец, как правильно написать этот триггер?

1 Ответ

0 голосов
/ 21 января 2019

Вам нужно использовать 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 ;
...