Je to pravděpodobně obchodní logika, která pravděpodobně nepatří do vaší vrstvy úložiště dat. Lze to však provést pomocí spouštěčů .
Můžete vytvořit BEFORE UPDATE
spouštěč, který vyvolá chybu, pokud se má aktualizovat "uzamčený" záznam; protože před dojde k chybě je operace provedena, MySQL v ní přestane pokračovat. Pokud chcete také zabránit smazání záznamu, budete muset vytvořit podobný spouštěč BEFORE DELETE
.
Chcete-li zjistit, zda je záznam "uzamčený", můžete vytvořit logickou hodnotu locked
sloupec:
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 ...;
Upozorňujeme, že SIGNAL
byl představen v MySQL 5.5. V dřívějších verzích musíte provést nějakou chybnou akci, která způsobí, že MySQL vyvolá chybu:Často volám neexistující proceduru, např. s CALL raise_error;
Znovu, pokud naprosto musíte umístit tuto logiku do vrstvy úložiště – a nemůže identifikovat uzamčené záznamy žádným jiným způsobem než PK – mohli byste pevně zakódujte test do svého spouštěče; například k "uzamčení" záznamu pomocí 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 ;
Ale to je naprosto hrozné a udělal bych téměř cokoliv vyhnout se tomu, kdykoli je to možné.