MYSQL存储过程select语句select不正确的ID
Posted
技术标签:
【中文标题】MYSQL存储过程select语句select不正确的ID【英文标题】:MYSQL stored procedure select statement select incorrect ID 【发布时间】:2012-03-11 03:50:52 【问题描述】:在存储过程方面,我不是知识最渊博的人,这个问题让我大吃一惊!
基本上我只是想运行一个简单的更新语句,但是当我在过程中运行它时,我选择更新行的用户 ID 不正确,但是如果我在过程之外运行相同的选择语句,它返回预期的结果。
DELIMITER $$
CREATE PROCEDURE catchUpBbs_Users()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE deleteUser, keepUser VARCHAR(255);
DECLARE id INT;
DECLARE cur1 CURSOR FOR SELECT u.username, b.username, b.id from users u RIGHT JOIN bbs_users b ON u.username = b.username WHERE u.username IS NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
allusers: LOOP
FETCH cur1 INTO keepUser, deleteUser, id;
IF done THEN
LEAVE allusers;
END IF;
IF deleteUser != 'anonymous' THEN
-- This is where the problems start
-- Just for test purposes, returns correct id and username
SELECT id, username FROM bbs_users WHERE username = deleteUser;
-- Just for test purposes, return INCORRECT id, but the CORRECT username
SELECT id, username FROM bbs_users WHERE username = 'anonymous';
-- The update statement that does not work as I want it to, sets the user_id to be what it already it, so no updates occur
UPDATE bbs_posts SET user_id = (SELECT id FROM bbs_users WHERE username = 'anonymous') WHERE user_id = (SELECT id FROM bbs_users WHERE username = deleteUser);
-- delete the user from the bbs_users table
DELETE FROM bbs_users WHERE username = deleteUser;
END IF;
END LOOP allusers;
CLOSE cur1;
END;
$$
DELIMITER ;
当我调用该过程时,两个测试选择语句返回:
1) 这些结果都是正确的
SELECT id, username FROM bbs_users WHERE username = deleteUser;
+------+----------+
| id | username |
+------+----------+
| 13 | deleteme |
+------+----------+
2) ID不正确,但是用户名不正确,ID应该是1
SELECT id, username FROM bbs_users WHERE username = 'anonymous';
+------+-----------+
| id | username |
+------+-----------+
| 13 | anonymous |
+------+-----------+
当我运行相同的程序时,减去变量,过程外的 select 语句都返回正确的结果
1) 这些结果都是正确的
SELECT id, username FROM bbs_users WHERE username = 'deleteme';
+----+----------+
| id | username |
+----+----------+
| 13 | deleteme |
+----+----------+
2) 这些结果都是正确的
SELECT id, username FROM bbs_users WHERE username = 'anonymous';
+----+-----------+
| id | username |
+----+-----------+
| 1 | anonymous |
+----+-----------+
我做错了什么?在使用存储过程时,在选择和变量方面有什么我错过的吗?
任何帮助或建议将不胜感激
【问题讨论】:
【参考方案1】:问题是您在游标中定义了一个名为 id
的标量变量,并且您正在选择它,因此游标内的两个 select 语句都使用该存储的标量值来引用 id
.
为了获得“正确”的值,您需要消除所有歧义:
-- Just for test purposes, returns correct id and username
SELECT b.id, b.username FROM bbs_users b WHERE b.username = deleteUser;
-- Just for test purposes, return INCORRECT id, but the CORRECT username
SELECT b.id, b.username FROM bbs_users b WHERE b.username = 'anonymous';
【讨论】:
谢谢!这解决了我的问题,你教会了我一些新东西。【参考方案2】:你有没有试过在 end if 和 end 循环之前重复句子“FETCH cur1 INTO keepUser, deleteUser, id”...
【讨论】:
【参考方案3】:以下工作是否更好。清理了您多次有效执行相同查询的位置。抱歉,如果我误解了这个问题 - 但如果我理解正确,那么下面的查询应该会更有效地运行。还会删除所有不明确的字段名称。
DELIMITER $$
CREATE PROCEDURE catchUpBbs_Users()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE oldID INT;
DECLARE newID INT;
DECLARE cur1 CURSOR FOR
SELECT b.id
FROM users u
RIGHT JOIN bbs_users b
ON u.username = b.username
WHERE u.username IS NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
// Get the new id
SELECT id INTO newID FROM bbs_users WHERE username = 'anonymous';
OPEN cur1;
allusers: LOOP
FETCH cur1 INTO oldID; // b.id
IF done THEN
LEAVE allusers;
END IF;
IF deleteUser != 'anonymous' THEN
-- Just for test purposes, returns correct id and username
SELECT id, username FROM bbs_users WHERE id = oldID;
-- Just for test purposes, return INCORRECT id, but the CORRECT username
SELECT id, username FROM bbs_users WHERE id = newID;
UPDATE bbs_posts SET user_id = newID WHERE user_id = oldID;
-- delete the user from the bbs_users table
DELETE FROM bbs_users WHERE id = oldID;
END IF;
END LOOP allusers;
CLOSE cur1;
END;
$$
DELIMITER ;
【讨论】:
以上是关于MYSQL存储过程select语句select不正确的ID的主要内容,如果未能解决你的问题,请参考以下文章
MySQl 错误 #1064 存储过程 IF ELSE 带有多个 SELECT 语句
mysql 存储过程中的select into outfile语句生成的文件放哪里
存储过程中的 MySQL select 语句返回的结果与 proc 外部不同