Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como definir uma linha do MySQL para READ-ONLY?


É provável que seja lógica de negócios, que provavelmente não pertence à sua camada de armazenamento de dados. No entanto, isso pode ser feito usando triggers .

Você pode criar um BEFORE UPDATE gatilho que gera um erro se um registro "bloqueado" estiver prestes a ser atualizado; uma vez que ocorre um erro antes a operação é realizada, o MySQL deixa de prosseguir com ela. Se você também quiser evitar que o registro seja excluído, será necessário criar um gatilho semelhante BEFORE DELETE .

Para determinar se um registro está "bloqueado", você pode criar um booleano locked coluna:
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 ...;

Observe que SIGNAL foi introduzido no MySQL 5.5. Nas versões anteriores, você deve executar alguma ação errônea que faça com que o MySQL gere um erro:Eu frequentemente chamo um procedimento inexistente, por exemplo. com CALL raise_error;

Novamente, se você absolutamente deve colocar essa lógica na camada de armazenamento - e não pode identificar os registros bloqueados por nenhum outro meio que não seja o PK - você poderia codifique o teste em seu gatilho; por exemplo, para "bloquear" o registro com 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 ;

Mas isso é absolutamente horrível e eu faria quase tudo para evitá-lo sempre que possível.