sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo configurar una fila de MySQL en SOLO LECTURA?

Es probable que se trate de una lógica comercial, que probablemente no pertenezca a su capa de almacenamiento de datos. Sin embargo, aún se puede lograr usando disparadores .

Puedes crear un BEFORE UPDATE activador que genera un error si un registro "bloqueado" está a punto de actualizarse; ya que se produce un error antes se lleva a cabo la operación, MySQL deja de continuar con ella. Si también desea evitar que se elimine el registro, deberá crear un disparador similar BEFORE DELETE .

Para determinar si un registro está "bloqueado", puede crear un booleano locked columna:

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

Tenga en cuenta que SIGNAL fue introducido en MySQL 5.5. En versiones anteriores, debe realizar alguna acción errónea que hace que MySQL genere un error:a menudo llamo a un procedimiento inexistente, p. con CALL raise_error;

De nuevo, si absolutamente debes colocar esta lógica en la capa de almacenamiento, y no puede identificar los registros bloqueados por ningún otro medio que no sea el PK, podría codifique la prueba en su disparador; por ejemplo, para "bloquear" el registro 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 ;

Pero esto es absolutamente horrible y haría casi cualquier cosa para evitarlo siempre que sea posible.