Vig*_*igs 12 mysql sql stored-procedures variable-declaration
我查看了大量的教程,手册和文档,但我仍然无法使用它.
我正在尝试使用phpMyAdmin创建存储过程.
我似乎无法在这里找到错误,sql错误是如此模糊......
CREATE PROCEDURE insertToonOneShot(IN locale CHAR(2), IN name VARCHAR(16), IN realm VARCHAR(24), IN faction CHAR(1), IN toon_level INT, IN class_name INT)
BEGIN
DECLARE @realmID INT;
DECLARE @classID INT;
DECLARE @toonID INT;
SET @realmID = SELECT id FROM realms WHERE realms.name = realm;
SET @classID = SELECT id FROM classes WHERE classes.name = class_name;
IF NOT @realmID IS NULL AND NOT @classID IS NULL AND @toonID IS NULL THEN
INSERT INTO
toon (`locale`, `name`, `realm_id`, `faction`, `level`, `class_id`)
VALUES
(locale, name, @realmID, faction, toon_level, @classID);
END IF;
END;
Run Code Online (Sandbox Code Playgroud)
我现在得到的错误是:
#1064 - 您的SQL语法有错误; 检查与MySQL服务器版本对应的手册,以便在@realmID INT附近使用正确的语法; DECLARE @classID INT; DECLARE @toonID INT; 在第3行设置@rea
可能是我曾经做过的更令人沮丧的事情之一......
我在网上看到很多教程在变量声明中使用@符号,而其他人没有使用它,我甚至看到一些使用VAR而不是DECLARE.什么是正确的语法?...
Gor*_*off 11
当你有子查询时,它需要有括号.这些线:
SET @realmID = SELECT id FROM realms WHERE realms.name = realm;
SET @classID = SELECT id FROM classes WHERE classes.name = class_name;
Run Code Online (Sandbox Code Playgroud)
应该:
SET @realmID = (SELECT id FROM realms WHERE realms.name = realm);
SET @classID = (SELECT id FROM classes WHERE classes.name = class_name);
Run Code Online (Sandbox Code Playgroud)
或者,更好的是,您不需要set:
SELECT @realmID := id FROM realms WHERE realms.name = realm;
SELECT @classID := id FROM classes WHERE classes.name = class_name;
Run Code Online (Sandbox Code Playgroud)
这样做的诀窍:
CREATE PROCEDURE insertToonOneShot(IN locale CHAR(2), IN name VARCHAR(16), IN realm VARCHAR(24), IN faction CHAR(1), IN toon_level INT, IN class_name VARCHAR(12))
BEGIN
SELECT @realmID := id FROM realms WHERE realms.name = realm;
SELECT @classID := id FROM classes WHERE classes.name = class_name;
SELECT @toonID := id FROM toon WHERE toon.name = name AND toon.realm_id = @realmID;
IF NOT @realmID IS NULL AND NOT @classID IS NULL AND @toonID IS NULL
THEN
INSERT INTO toon (`locale`, `name`, `class_id`, `realm_id`, `faction`, `level`)
VALUES (locale, name, @classID, @realmID, faction, toon_level);
END IF;
END;
//
Run Code Online (Sandbox Code Playgroud)
显然声明声明不是必需的......谁会知道?
感谢Gordon Linoff指出我正确的方向.
老问题,但我认为值得一提的是,它似乎是混淆了会话变量,它们@带有程序变量,而不是.
已接受的解决方案可以解决错误,但如果在过程外定义变量然后在内部使用,则可能会引入与变量范围相关的问题.解决此问题的正确方法是仅使用过程变量:
DELIMITER $$
CREATE PROCEDURE insertToonOneShot(
IN locale CHAR(2),
IN name VARCHAR(16),
IN realm VARCHAR(24),
IN faction CHAR(1),
IN toon_level INT,
IN class_name INT
)
BEGIN
DECLARE realmID INT;
DECLARE classID INT;
SELECT id INTO realmID FROM realms WHERE realms.name = realm LIMIT 1;
SELECT id INTO classID FROM classes WHERE classes.name = class_name LIMIT 1;
IF realmID IS NOT NULL AND classID IS NOT NULL THEN
INSERT INTO toon (`locale`, `name`, `realm_id`, `faction`, `level`, `class_id`)
VALUES (locale, name, realmID, faction, toon_level, classID);
END IF;
END$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)