Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie setze ich eine MySQL-Zeile auf schreibgeschützt?

Dies ist wahrscheinlich Geschäftslogik, die wahrscheinlich nicht in Ihre Datenspeicherschicht gehört. Es kann jedoch trotzdem mit Triggern erreicht werden .

Sie können einen BEFORE UPDATE erstellen Trigger, der einen Fehler auslöst, wenn ein "gesperrter" Datensatz aktualisiert werden soll; da vorher ein Fehler auftritt Wenn die Operation durchgeführt wird, hört MySQL auf, damit fortzufahren. Wenn Sie auch verhindern möchten, dass der Datensatz gelöscht wird, müssen Sie einen ähnlichen Trigger BEFORE DELETE erstellen .

Um festzustellen, ob ein Datensatz "gesperrt" ist, könnten Sie einen booleschen Wert locked erstellen Spalte:

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 ...;

Beachten Sie, dass SIGNAL wurde in MySQL 5.5 eingeführt. In früheren Versionen müssen Sie eine fehlerhafte Aktion ausführen, die dazu führt, dass MySQL einen Fehler ausgibt:Ich rufe oft eine nicht vorhandene Prozedur auf, z. mit CALL raise_error;

Nochmals, wenn Sie unbedingt müssen Platzieren Sie diese Logik in der Speicherschicht – und können die gesperrten Datensätze nicht durch andere Mittel als die PK identifizieren – Sie könnten codieren Sie den Test fest in Ihren Trigger; zum Beispiel, um den Datensatz mit id_column = 1234 zu "sperren". :

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 ;

Aber das ist absolut schrecklich und ich würde fast alles tun um es wann immer möglich zu vermeiden.