Как написать триггер для отмены удаления в MYSQL?

Я прочитал эту статью, но она не работает для удаления. Я получил эту ошибку, когда пытался создать триггер:

Выполнение SQL-скрипта на сервере

ОШИБКА: Ошибка 1363: В триггере УДАЛИТЬ отсутствует НОВАЯ строка

CREATE TRIGGER DeviceCatalog_PreventDeletion 
BEFORE DELETE on DeviceCatalog
FOR EACH ROW
BEGIN
    DECLARE dummy INT;

    IF old.id = 1 or old.id =2 THEN
        SELECT * FROM DeviceCatalog WHERE DeviceCatalog.id=NEW.id;
    END IF;
END; 

Выполнение SQL-скрипта завершено: операторы: 4 успешно выполнены, 1 не удалось

Ответ 1

Попробуйте что-то вроде этого -

DELIMITER $$

CREATE TRIGGER trigger1
BEFORE DELETE
ON table1
FOR EACH ROW
BEGIN
  IF OLD.id = 1 THEN -- Abort when trying to remove this record
    CALL cannot_delete_error; -- raise an error to prevent deleting from the table
  END IF;
END
$$

DELIMITER ;

Ответ 2

Улучшение @Devart (принятого) ответа с комментарием @MathewFoscarini о Команда MySQL SIGNAL вместо того, чтобы поднимать ошибку вызвав несущественную процедуру, вы можете сигнализировать о своем пользовательском сообщении об ошибке.

DELIMITER $$

CREATE TRIGGER DeviceCatalog_PreventDeletion
BEFORE DELETE ON DeviceCatalog
FOR EACH ROW
BEGIN

  IF old.id IN (1,2) THEN -- Will only abort deletion for specified IDs
    SIGNAL SQLSTATE '45000' -- "unhandled user-defined exception"
      -- Here comes your custom error message that will be returned by MySQL
      SET MESSAGE_TEXT = 'This record is sacred! You are not allowed to remove it!!';
  END IF;

END
$$

DELIMITER ;

SQLSTATE 45000 был выбран как Справочное руководство по MySQL предлагает:

Чтобы сигнализировать общее значение SQLSTATE, используйте "45000", что означает "необработанное пользовательское исключение".

Таким образом ваше пользовательское сообщение будет отображаться пользователю всякий раз, когда он пытается удалить идентификаторы записей 1 или 2. Кроме того, если никакие записи не должны быть удалены из таблицы, вы можете просто удалить строки IF .. THEN и END IF;. Это предотвратит удаление записей ЛЮБОЙ в таблице.

Ответ 3

Ну, сообщения об ошибках сообщают вам достаточно четко: в триггере DELETE нет NEW.

  • В триггере INSERT вы можете получить новые значения с помощью NEW.
  • В триггере UPDATE вы можете получить доступ к новым значениям с помощью NEW., а старые - с вами - OLD.
  • В триггере DELETE вы можете использовать старые значения с помощью OLD.

Просто нет смысла иметь NEW в DELETE, так же как OLD в INSERT не имеет смысла.

Ответ 4

Как говорится в ошибке: для удаления нет новой переменной.

вы можете использовать new.id только для вставки и обновления. Вместо этого используйте old.id.

SELECT * FROM DeviceCatalog WHERE DeviceCatalog.id=old.id;