2012-05-08 6 views
31

Tengo una fila en una tabla que no quiero cambiar (nunca).¿Cómo configurar una fila de MySQL para READ-SOLAMENTE?

¿Es posible establecer una fila de MySQL en READ-SOLAMENTE para que no se pueda actualizar de ninguna manera? ¿Si es así, cómo?

Si no, ¿es posible establecer un valor permanente en una de las columnas de esa fila para que no se pueda cambiar? ¿Si es así, cómo?

Gracias.

+3

No, no existe una fila de solo lectura. Pero puede configurar cuentas MySQL de modo que un usuario en particular no tenga permisos de actualización/eliminación. –

+0

Poss dup: http://stackoverflow.com/questions/3878672/how-to-lock-particular-row-in-mysql –

+0

@Marc B: Entonces, ¿ninguna de las opciones que mencioné están disponibles? Confirma, porque la solución de permisos de usuario que mencionaste no resolverá mi problema desafortunadamente. – ProgrammerGirl

Respuesta

34

Es probable que sea una lógica de negocios, que probablemente no pertenezca a la capa de almacenamiento de datos. Sin embargo, puede lograrse usando triggers.

Puede crear un disparador BEFORE UPDATE que genera un error si se va a actualizar un registro "bloqueado"; ya que se produce un error antes de se lleva a cabo la operación, MySQL deja de continuar con él. Si también desea evitar que se elimine el registro, deberá crear un desencadenador similar BEFORE DELETE.

Para determinar si un registro está "bloqueado", se puede crear una columna booleana locked:

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 se introdujo en MySQL 5.5. En versiones anteriores, debe realizar alguna acción errónea que provoque que MySQL presente un error: a menudo llamo a un procedimiento inexistente, p. con CALL raise_error;


I cannot create an additional column on this table, but the row has a unique id in one of the columns, so how would I do this for that scenario?

Una vez más, si absolutamente necesario lugar esta lógica en la capa de almacenamiento y no puede identificar los registros bloqueados mediante cualquier medio que no sea el PK-te podía código el prueba en tu gatillo; 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 que haría casi cualquier cosa de evitar siempre que sea posible.

+0

Gracias por una solución muy interesante. No puedo crear una columna adicional en esta tabla, pero la fila tiene una identificación única en una de las columnas, entonces, ¿cómo haría esto para ese escenario? – ProgrammerGirl

+0

@Programador: simplemente prueba en ese 'id' en la declaración' IF' del desencadenador: 'IF OLD.column <=> 'unique_id' THEN ...'. – eggyal

+2

Ahora hay una solución poco ortodoxa. Me gusta. +1 recuerda que solo puedes tener un disparador (por evento por mesa) en mysql, así que si ya tienes o necesitas otro disparador en el futuro ... deberías combinarlos en uno. – Kris

Cuestiones relacionadas