Dette er sandsynligvis forretningslogik, som sandsynligvis ikke hører hjemme i dit datalagerlag. Det kan dog ikke desto mindre opnås ved hjælp af triggere .
Du kan oprette en BEFORE UPDATE
trigger, der rejser en fejl, hvis en "låst" post er ved at blive opdateret; da der opstår en fejl før operationen udføres, ophører MySQL med at fortsætte med den. Hvis du også vil forhindre posten i at blive slettet, skal du oprette en lignende trigger BEFORE DELETE
.
For at afgøre, om en post er "låst", kan du oprette en boolsk locked
kolonne:
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 ...;
Bemærk, at SIGNAL
blev introduceret i MySQL 5.5. I tidligere versioner skal du udføre en eller anden fejlagtig handling, der får MySQL til at rejse en fejl:Jeg kalder ofte en ikke-eksisterende procedure, f.eks. med CALL raise_error;
Igen, hvis du absolut skal placere denne logik i lagerlaget – og kan ikke identificere de låste poster på andre måder end PK’en – du kunne hårdkode testen ind i din trigger; for eksempel at "låse" 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 her er helt forfærdeligt og jeg ville gøre næsten alt for at undgå det, når det er muligt.