我创建了这个小存储过程,从我的“qrcode”表中删除一行。
由于限制,我之前更新了所有子行,效果很好。
但是,执行此过程...会从表中删除所有行!!!!
我添加了日志,看到ID参数传递正确。
这就是删除查询忽略 WHERE 子句的方式。
最坏的情况下,我应该有一个错误,但是,没有。实在是太暴力了
我到处都找过了,但我真的不明白我在这里做什么。
有人来帮助我吗?
提前致谢。
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_delete_qrcode`( IN ID INT, OUT AFFECTED_ROWS INT)
BEGIN
DECLARE EXIT HANDLER FOR sqlexception
BEGIN
ROLLBACK;
RESIGNAL;
END;
SELECT concat('ID=', ID) as log;
START TRANSACTION;
SET FOREIGN_KEY_CHECKS=0;
update `qrcode` set `parentId`=NULL where `parentId`=ID;
SET FOREIGN_KEY_CHECKS=1;
delete FROM `qrcode` where `id`=ID;
SET AFFECTED_ROWS = ROW_COUNT();
SELECT @AFFECTED_ROWS;
COMMIT;
END
表格定义:
CREATE TABLE `QRCode` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`description` varchar(255) DEFAULT NULL,
`parentId` int DEFAULT NULL,
`rank` int DEFAULT '0',
`enabled` tinyint NOT NULL DEFAULT '1',
`createdBy` int DEFAULT NULL,
`createdDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedBy` int DEFAULT NULL,
`updatedDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `IDX_QRCode_ParentId` (`parentId`),
CONSTRAINT `qrcode_ibfk_1` FOREIGN KEY (`parentId`) REFERENCES `QRCode` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
通过在 SQL Workbench 编辑器中执行相同的操作,它可以工作! 显然,我什么都不懂!请帮忙。
SET @ID =28;
SET FOREIGN_KEY_CHECKS=0;
update `qrcode` set `parentId`=NULL where `parentId`=@ID;
delete FROM `qrcode` where `id`=@ID;
SET FOREIGN_KEY_CHECKS=1;
永远不要使用与列名相同的局部变量名称!!!
当它们具有相同的名称(不区分大小写)时,该名称将无条件地被视为变量名。因此你的
... where `id`=ID ...
比较变量和变量,因此它始终为 TRUE(直到变量为 NULL)。
或者至少指定表别名:
... where qrcode.id=ID ...
。在这种情况下 qrcode.id
不能被视为变量..
尽量不要使用
ID
作为存储过程中的参数。
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_delete_qrcode`( IN delete_id INT, OUT AFFECTED_ROWS INT)
BEGIN
DECLARE EXIT HANDLER FOR sqlexception
BEGIN
ROLLBACK;
RESIGNAL;
END;
SELECT concat('ID=', delete_id) as log;
START TRANSACTION;
SET FOREIGN_KEY_CHECKS=0;
update `qrcode` set `parentId`=NULL where `parentId`=delete_id;
SET FOREIGN_KEY_CHECKS=1;
delete FROM `qrcode` where `id`=delete_id;
SET AFFECTED_ROWS = ROW_COUNT();
SELECT @AFFECTED_ROWS;
COMMIT;
END