为啥 MySQL WorkBench 在使用游标时忽略了我的 SIGNAL SQLSTATE?
Posted
技术标签:
【中文标题】为啥 MySQL WorkBench 在使用游标时忽略了我的 SIGNAL SQLSTATE?【英文标题】:Why MySQL WorkBench is ignoring my SIGNAL SQLSTATE when using cursors?为什么 MySQL WorkBench 在使用游标时忽略了我的 SIGNAL SQLSTATE? 【发布时间】:2021-12-31 03:10:49 【问题描述】:首先,代码有点乱,但我不能帮它分配。回到问题,如果 aux SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Error: Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragón'; 时它不起作用。即使我把它放在其他任何东西之前,它也会把它当作什么都没有。我检查了代码,它似乎正在完全执行(它没有退出游标,而是进入了所有的 if),除了 SIGNAL SQLSTATE 之外,一切都在完美执行。
我一直在搜索,但没有发现任何关于 SIGNAL SQLSTATE 与游标一起使用时不起作用的信息。但是每次我在触发器中声明一个游标(即使我不使用它)它都会忽略我的 SIGNAL SQLSTATE。有没有我遗漏的 sintaxis 东西?
这是我必须为分配做的触发器:
CREATE TRIGGER check_if_unlocked BEFORE INSERT ON mata
FOR EACH ROW
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE nDragonesNecesarios INT; #El numero de dragones necesarios a matar para poder matar al siguiente
DECLARE nombrePersonajeAux VARCHAR(250);
DECLARE aux INT; #albergará el numero de dragones que ha matado un personaje
DECLARE curMagos CURSOR FOR
SELECT DISTINCT magoCompone.nombreMago
FROM magoCompone
WHERE magoCompone.idEscuadron = NEW.idEscuadron;
DECLARE curGuerreros CURSOR FOR
SELECT DISTINCT guerreroCompone.nombreGuerrero
FROM guerreroCompone
WHERE guerreroCompone.idEscuadron = NEW.idEscuadron;
DECLARE curTanques CURSOR FOR
SELECT DISTINCT tanqueCompone.nombreTanque
FROM tanqueCompone
WHERE tanqueCompone.idEscuadron = NEW.idEscuadron;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET nDragonesNecesarios = (SELECT COUNT(*)
FROM dragon
WHERE dragon.vida < (SELECT dragon.vida
FROM dragon
WHERE dragon.nombreDragonDesbloqueador = NEW.nombreDragon));
#Recorro los magos que pertenezcan al escuadrón
OPEN curMagos;
read_loop_mago: LOOP
FETCH curMagos INTO nombrePersonajeAux;
IF done THEN
LEAVE read_loop_mago;
END IF;
SET aux = (SELECT COUNT(*)
FROM magoCompone inner join mata on magoCompone.idEscuadron = mata.idEscuadron
WHERE magoCompone.nombreMago = nombrePersonajeAux);
IF aux < nDragonesNecesarios THEN # Ha matado a menos dragones de los necesarios
SET done = true;
SIGNAL SQLSTATE '02000'
SET MESSAGE_TEXT = 'Error: Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragón';
END IF;
END LOOP;
CLOSE curMagos;
SET done = FALSE;
#Recorro los guerreros que pertenezcan al escuadrón
OPEN curGuerreros;
read_loop_guerrero: LOOP
FETCH curGuerreros INTO nombrePersonajeAux;
IF done THEN
LEAVE read_loop_guerrero;
END IF;
SET aux = (SELECT COUNT(*)
FROM guerreroCompone inner join mata on guerreroCompone.idEscuadron = mata.idEscuadron
WHERE guerreroCompone.nombreGuerrero = nombrePersonajeAux);
IF aux < nDragonesNecesarios THEN # Ha matado a menos dragones de los necesarios
SET done = true;
SIGNAL SQLSTATE '02000'
SET MESSAGE_TEXT = 'Error: Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragón';
END IF;
END LOOP;
CLOSE curGuerreros;
SET done = FALSE;
#Recorro los tanques que pertenezcan al escuadrón
OPEN curTanques;
read_loop_tanque: LOOP
FETCH curTanques INTO nombrePersonajeAux;
IF done THEN
LEAVE read_loop_tanque;
END IF;
SET aux = (SELECT COUNT(*)
FROM tanqueCompone inner join mata on tanqueCompone.idEscuadron = mata.idEscuadron
WHERE tanqueCompone.nombreTanque = nombrePersonajeAux);
IF aux < nDragonesNecesarios THEN # Ha matado a menos dragones de los necesarios
SET done = true;
SIGNAL SQLSTATE '02000'
SET MESSAGE_TEXT = 'Error: Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragón';
END IF;
END LOOP;
CLOSE curTanques;
END$$
DELIMITER ;
感谢您的关注。
【问题讨论】:
【参考方案1】:您需要在缩短的示例中像这里一样声明一个退出处理程序
DECLARE EXIT HANDLER FOR SQLSTATE '02000'
BEGIN SET @a := 23;
SIGNAL SQLSTATE '02000'
SET MESSAGE_TEXT = 'Error: Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragón';
END;
CREATE Table A ( A1 int , A2 int); INSERT INTO A VALUES( 5,2),(7,1); CREATE Table B ( B1 int, B2 int, B3 int, B4 int, B5 int, B6 int); INSERT INTO B VALUES(5,4,6,1,2,0)
CREATE TRIGGER abdtrg Before INSERT ON A FOr EACH ROW BEGIN DECLARE done INT DEFAULT FALSE; DECLARE nombrePersonajeAux INTEGER; DECLARE nombrePersonajeAux2 INTEGER; DECLARE curMagos CURSOR FOR SELECT A1,A2 FROM A; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; DECLARE EXIT HANDLER FOR SQLSTATE '02000' BEGIN SET @a := 23; SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Error: Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragón'; END; OPEN curMagos; read_loop_mago: LOOP FETCH curMagos INTO nombrePersonajeAux,nombrePersonajeAux2; SET @a := -1; IF done THEN LEAVE read_loop_mago; END IF; IF nombrePersonajeAux > nombrePersonajeAux2 THEN # Ha matado a menos dragones de los necesarios SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Error: Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragón'; SET done := true; LEAVE read_loop_mago; END IF; END LOOP read_loop_mago; CLOSE curMagos; END
错误:Algún integrante del escuadrón no tiene desbloqueados los dragones necesarios para matar a este dragonINSERT INTO A VALUES(1,1)
A1 | A2 | @一种 -: | -: | -: 5 | 2 | 23 7 | 1 | 23SELECT *,@a FROM A
db小提琴here
【讨论】:
您好,信号 sqlstate 现在可以工作了,但它现在不允许我在表中插入任何内容,即使条件为 false 也总是弹出错误 你问我怎么做,我告诉过你,你要id调试什么,你必须自己做。如果你想对行为做一个 dbfiddle,我可以看看它。以上是关于为啥 MySQL WorkBench 在使用游标时忽略了我的 SIGNAL SQLSTATE?的主要内容,如果未能解决你的问题,请参考以下文章
请问为啥MySQL使用游标进行insert操作时,末行会被插入两次?下附代码
mysql workbench在建表以后想把已有的字段设置为AI,但设不了。为啥的
为啥 MySQL Workbench 表数据导入向导会导入 0 条记录?