Dit is waarschijnlijk bedrijfslogica, die waarschijnlijk niet thuishoort in uw gegevensopslaglaag. Het kan echter niettemin worden bereikt met behulp van triggers .
U kunt een BEFORE UPDATE
. maken trigger die een foutmelding geeft als een "vergrendeld" record op het punt staat te worden bijgewerkt; omdat er een fout optreedt voor de operatie wordt uitgevoerd, stopt MySQL ermee verder te gaan. Als u ook wilt voorkomen dat de record wordt verwijderd, moet u een vergelijkbare trigger maken BEFORE DELETE
.
Om te bepalen of een record "vergrendeld" is, kunt u een boolean locked
. maken kolom:
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 ...;
Merk op dat SIGNAL
werd geïntroduceerd in MySQL 5.5. In eerdere versies moet u een foutieve actie uitvoeren waardoor MySQL een fout genereert:ik noem vaak een niet-bestaande procedure, b.v. met CALL raise_error;
Nogmaals, als je absoluut moet plaats deze logica in de opslaglaag - en kan de vergrendelde records niet identificeren op een andere manier dan de PK - u zou codeer de test hard in uw trigger; bijvoorbeeld om het record te "vergrendelen" met 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 ;
Maar dit is absoluut verschrikkelijk en ik zou bijna alles doen om het waar mogelijk te vermijden.