Si j’obtiens un déclencheur avant la mise à jour sur une table, comment je peux jeter une erreur qui empêche la mise à jour sur cette table ?
Réponses
Trop de publicités?Voici un hack peut fonctionner. Il n’est pas propre, mais on dirait qu’il pourrait fonctionner :
Essentiellement, vous essayez de mettre à jour une colonne qui n’existe pas.
Malheureusement, la réponse fournie par @RuiDC ne fonctionne pas dans les versions de MySQL antérieures à 5,5 parce qu'il n'y a pas de mise en œuvre de SIGNAL pour les procédures stockées.
La solution que j'ai trouvé est de simuler un signal de jeter un table_name doesn't exist
d'erreur en poussant un message d'erreur personnalisé dans l' table_name
.
Le hack pourraient être mises en œuvre à l'aide de déclencheurs ou à l'aide d'une procédure stockée. Je décris les deux options ci-dessous en suivant l'exemple utilisé par @RuiDC.
À l'aide de déclencheurs
DELIMITER $$
-- before inserting new id
DROP TRIGGER IF EXISTS before_insert_id$$
CREATE TRIGGER before_insert_id
BEFORE INSERT ON test FOR EACH ROW
BEGIN
-- condition to check
IF NEW.id < 0 THEN
-- hack to solve absence of SIGNAL/prepared statements in triggers
UPDATE `Error: invalid_id_test` SET x=1;
END IF;
END$$
DELIMITER ;
À l'aide d'une procédure stockée
Procédures stockées vous permet d'utiliser sql dynamique, ce qui rend possible l'encapsulation de l'erreur des fonctionnalités de génération en une seule procédure. Le contrepoint est que nous devons contrôler les applications insertion/mise à jour de méthodes, de sorte qu'ils utilisent seulement notre procédure stockée (pas l'octroi direct de privilèges pour INSÉRER/mettre à JOUR).
DELIMITER $$
-- my_signal procedure
CREATE PROCEDURE `my_signal`(in_errortext VARCHAR(255))
BEGIN
SET @sql=CONCAT('UPDATE `', in_errortext, '` SET x=1');
PREPARE my_signal_stmt FROM @sql;
EXECUTE my_signal_stmt;
DEALLOCATE PREPARE my_signal_stmt;
END$$
CREATE PROCEDURE insert_test(p_id INT)
BEGIN
IF NEW.id < 0 THEN
CALL my_signal('Error: invalid_id_test; Id must be a positive integer');
ELSE
INSERT INTO test (id) VALUES (p_id);
END IF;
END$$
DELIMITER ;