【问题标题】:Cannot declare a variable in a stored procedure无法在存储过程中声明变量
【发布时间】:2014-01-07 08:07:23
【问题描述】:

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

ERROR 1064 (42000):您的 SQL 语法有错误;检查 与您的 MySQL 服务器版本相对应的手册 在 '@userID INT; 附近使用的语法; DECLARE @cursorUserID CURSOR FOR SELECT (MAX(userID) + 1) FROM Use' 在第 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 ;

【问题讨论】:

  • 为什么你可能需要一个光标来只选择一行..?
  • 使用此代码我得到错误:'ERROR 1064 (42000): You have an error in your SQL syntax;检查与您的 MySQL 服务器版本相对应的手册,以获取在 '@userID int; 附近使用的正确语法;将@cursorUserID 声明为光标;

标签: mysql sql stored-procedures


【解决方案1】:
  1. 正如其他人已经提到的那样,您正在混合局部变量(变量名前没有 @)和用户(会话)变量(变量名前有 @ )。 DECLARE仅用于局部变量。会话变量始终可用,不需要声明。

  2. 最好不要为变量和过程参数指定与表中的列名相同的名称。当 MySQL 无法确定您使用变量或列的实际含义时,它很容易破坏您的代码。

  3. 您绝对不需要游标(与 Oracle 中的 plsql 不同)通过使用聚合函数(在您的情况下为 MAX())返回标量值。只需将选择放在括号中即可。

也就是说,您的代码的语法正确版本可能看起来像这样

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 列。改用它。

【讨论】:

  • 感谢它的帮助。
【解决方案2】:

试试这个

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 ;

【讨论】:

    【解决方案3】:

    试试这个

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

    【讨论】:

    • 使用此代码我得到错误:'ERROR 1064 (42000): You have an error in your SQL syntax;检查与您的 MySQL 服务器版本相对应的手册,以获取在 '@userID INT; 附近使用的正确语法; DECLARE @cursorUserID CURSOR FOR SELECT (MAX(userID) + 1) FROM Use' at line 3'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 2014-08-08
    • 2016-07-19
    • 1970-01-01
    • 2012-06-20
    相关资源
    最近更新 更多