Detta är sannolikt affärslogik, som förmodligen inte hör hemma i ditt datalagringslager. Det kan dock ändå utföras med utlösare .
Du kan skapa en BEFORE UPDATE
trigger som ger upphov till ett fel om en "låst" post är på väg att uppdateras; eftersom ett fel inträffar före operationen utförs, upphör MySQL att fortsätta med den. Om du också vill förhindra att posten raderas måste du skapa en liknande utlösare BEFORE DELETE
.
För att avgöra om en post är "låst" kan du skapa en boolesk locked
kolumn:
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 ...;
Observera att SIGNAL
introducerades i MySQL 5.5. I tidigare versioner måste du utföra någon felaktig åtgärd som gör att MySQL ger upp ett fel:Jag kallar ofta en icke-existerande procedur, t.ex. med CALL raise_error;
Återigen, om du absolut måste placera denna logik i lagringslagret – och kan inte identifiera de låsta posterna på något annat sätt än PK – du kan hårdkoda testet i din trigger; till exempel för att "låsa" posten med 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 ;
Men det här är helt hemskt och jag skulle göra nästan vad som helst för att undvika det när det är möjligt.