Mysql
 sql >> Database >  >> RDS >> Mysql

Come impostare una riga MySQL su SOLA LETTURA?

È probabile che si tratti di logica aziendale, che probabilmente non appartiene al livello di archiviazione dei dati. Tuttavia, può comunque essere realizzato utilizzando trigger .

Puoi creare un BEFORE UPDATE trigger che genera un errore se un record "bloccato" sta per essere aggiornato; poiché si verifica un errore prima l'operazione è stata eseguita, MySQL smette di procedere con essa. Se vuoi anche impedire l'eliminazione del record, devi creare un attivatore simile BEFORE DELETE .

Per determinare se un record è "bloccato", puoi creare un locked booleano colonna:

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

Tieni presente che SIGNAL è stato introdotto in MySQL 5.5. Nelle versioni precedenti, è necessario eseguire alcune azioni errate che causano la generazione di un errore da parte di MySQL:spesso chiamo una procedura inesistente, ad es. con CALL raise_error;

Di nuovo, se devi assolutamente posizionare questa logica nel livello di archiviazione e non è possibile identificare i record bloccati con mezzi diversi dalla PK:potreste codificare il test nel trigger; ad esempio, per "bloccare" il record con 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 ;

Ma questo è assolutamente orribile e farei quasi tutto per evitarlo quando possibile.