无法在存储过程中声明变量

时间:2014-01-07 08:07:23

标签: mysql sql stored-procedures

我无法在存储过程中声明mysql变量。此外,我无法打开光标,我一直得到同样的错误:

  

错误1064(42000):您的SQL语法有错误;检查   手册,对应右边的MySQL服务器版本   要在'@userID INT附近使用的语法;         DECLARE @cursorUserID CURSOR FOR SELECT(MAX(userID)+ 1)FROM使用'在第3行。

以下是代码:

use phpBank;
DELIMITER //
CREATE PROCEDURE newUser()
BEGIN
       DECLARE @userID INT;
       DECLARE @cursorUserID CURSOR FOR SELECT (MAX(userID) + 1) FROM Users;
       OPEN @newUserID;
END;
//
DELIMITER ;

3 个答案:

答案 0 :(得分:1)

  1. 正如其他人已经提到过的那样,你在混合局部变量(变量名前没有@)和用户(会话)变量(前面有@)变量名称)。 DECLARE仅用 作为局部变量。会话变量始终可用,不需要声明。

  2. 最好不要让变量和过程参数与表中的列名相同。当MySQL无法确定您使用变量或列的实际意图时,它可以轻松地破坏您的代码。

  3. 肯定不需要游标(与Oracle中的plsql不同)通过使用聚合函数(在您的情况下为MAX())来返回标量值。只需在括号中选择一个。

  4. 据说,代码的语法正确版本可能看起来像这样

    DELIMITER $$
    CREATE PROCEDURE newUser()
    BEGIN
        DECLARE newid INT;
    
        SET newid = (SELECT COALESCE(MAX(userID), 0) + 1 FROM Users);
        SELECT newid;
    END$$
    DELIMITER ;
    

    或从技术上讲,你也可以(但不推荐)这个

    DELIMITER $$
    CREATE PROCEDURE newUser()
    BEGIN
        SET @newid = (SELECT COALESCE(MAX(userID), 0) + 1 FROM Users);
        SELECT @newid newid;
    END$$
    DELIMITER ;
    

    这是 SQLFiddle 演示


    现在,从程序名称和您尝试使用它的查询中推断,看起来您正在重新创建一个生成独特ID(最有可能是PK)的手动操作。 停止!不要这样做。它会创建竞争条件,并且在并发环境中无法正常工作,因为多个进程可能会获取相同的MAX(userID)值。

    在MySQL中生成唯一ID的唯一安全方法是auto_increment列。改为使用它。

答案 1 :(得分:0)

试试这个

use phpBank;

DELIMITER //
CREATE PROCEDURE newUser()

BEGIN
        DECLARE @userID int;
        DECLARE @cursorUserID AS CURSOR; 
        SET @cursorUserID = CURSOR FOR SELECT (MAX(userID) + 1) FROM Users;

        OPEN @newUserID;

END;
//
DELIMITER ;

答案 2 :(得分:0)

试试这个

DELIMITER //
    CREATE PROCEDURE newUser()
    BEGIN 
            DECLARE userID INT;
            DECLARE cursorUserID CURSOR FOR SELECT (MAX(userID) + 1) FROM Users;
            -- OPEN newUserID;

    END;
    //
    DELIMITER ;

CALL newUser();