Това вероятно е бизнес логика, която вероятно не принадлежи на вашия слой за съхранение на данни. Въпреки това, това може да бъде постигнато с помощта на тригери .
Можете да създадете BEFORE UPDATE
тригер, който предизвиква грешка, ако "заключен" запис предстои да бъде актуализиран; тъй като грешка възникне преди операцията е предприета, MySQL престава да продължи с нея. Ако искате да предотвратите изтриването на записа, ще трябва да създадете подобен тригер BEFORE DELETE
.
За да определите дали записът е "заключен", можете да създадете булев locked
колона:
ALTER TABLE my_table ADD COLUMN locked BOOLEAN NOT NULL DEFAULT FALSE;
DELIMITER ;;
CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.locked THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;
CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.locked THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;
DELIMITER ;
UPDATE my_table SET locked = TRUE WHERE ...;
Имайте предвид, че SIGNAL
беше въведен в MySQL 5.5. В по-ранни версии трябва да извършите някакво погрешно действие, което кара MySQL да изведе грешка:често извиквам несъществуваща процедура, напр. с CALL raise_error;
Отново, ако абсолютно трябва поставете тази логика в слоя за съхранение - и не можете да идентифицирате заключените записи чрез никакви средства, различни от PK - вие можете твърдо кодирайте теста във вашия тригер; например да "заключите" записа с id_column = 1234
:
DELIMITER ;;
CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;
CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;
DELIMITER ;
Но това е абсолютно ужасно и бих направил почти всичко за да го избягвате, когато е възможно.