Я не знаю, есть ли способ предотвратить удаление, если оно уже было вызвано, без какого-либо исключения.
Я думаю, что лучшим решением может быть вместо вызова delete для записи, которую вы хотите удалить / удалить, вы должны обновить поле, такое как "IsTrashed", в значение TRUE. А затем в триггере обновления посмотрите, было ли оно уже ИСТИНА и снова установлено на ИСТИНА (например, IF(OLD.IsTrashed && NEW.IsTrashed)
). Если это так, удалите его, в противном случае переместите его в корзину.
Единственная проблема, которая возникнет при использовании этого метода, - это если вы обновите другое поле (например, PostDate) потерянного элемента, NEW.IsTrashed и OLD.IsTrashed будут ИСТИНА, поэтому может показаться, что вы пытаетесь удалить его , но вы только обновляете PostDate. Вы можете либо проверить, что это единственное поле, которое было изменено (например, проверяя OLD.SomeField <> NEW.SomeField
для каждого другого поля), либо использовать поле, которое всегда будет сбрасывать его значение в NULL после оператора UPDATE. Что-то вроде "TrashNow". Таким образом, если TrashNow когда-либо имеет значение TRUE, вы знаете, что вы намеренно хотели очистить поле.
Тем не менее, это «поле сброса» - это просто потраченное впустую пространство. Я думаю, что лучшим решением этой проблемы является хранимая процедура ... что-то вроде:
CREATE PROCEDURE DeletePost (IN APostID INT)
BEGIN
IF ((SELECT InTrash FROM posts WHERE PostID = APostID LIMIT 1))
DELETE FROM posts WHERE PostID = APostID;
ELSE IF
UPDATE posts SET InTrash = TRUE WHERE PostID = APostID;
END IF;
END;
Предполагается, что у вас есть таблица posts с полями PostID (INT) и InTrash (любой целочисленный тип).
Вы бы назвали это так, чтобы удалить сообщение с PostID 123:
CALL DeletePost(123);