MYSQL存储过程select语句选择不正确的ID

时间:2012-02-20 19:38:24

标签: mysql database stored-procedures select

在存储过程方面,我不是最有知识能力的人,这个问题让我大吃一惊!

基本上我只是想尝试运行一个简单的更新语句,但是当我在程序中运行时,我选择更新行的用户ID是不正确的,但如果我在程序之外运行相同的select语句返回预期结果。

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 ;

当我调用该过程时,两个测试select语句返回:

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 |
+----+-----------+

我做错了什么?在使用存储过程时,在选择和变量方面有什么我错过的吗?

非常感谢任何帮助或建议

3 个答案:

答案 0 :(得分:2)

问题是你在游标中定义了一个名为id的标量变量,并且你正在选择它,因此游标中的两个select语句都使用存储的标量值来表示对{的所有引用{1}}。

为了获得“正确”值,您需要删除所有歧义:

id

答案 1 :(得分:0)

你有没有试过在结束循环之后和之前重复句子“FETCH cur1 INTO keepUser,deleteUser,id”...

答案 2 :(得分:0)

以下工作是否更好。已经清理了多次有效执行相同查询的位置。对不起,如果我误解了这个问题 - 但如果我理解正确,那么下面的查询应该更有效地运作。同时删除所有不明确的字段名称。

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 ;