我对MySQL很新。我必须使用输出参数调用存储过程。我在互联网上搜索了很多,但我找不到解决问题的正确方法。如果我用@outputParamName调用存储过程,它表示我有一个错误#1064接近NULL。如果我使用' outputParamName'来调用该过程。没有@它说它不是OUT或INOUT正确的参数。有人可以帮帮我吗? 存储过程只需要检查DB中的姓氏和名称是否存在于同一行:
CREATE PROCEDURE InsertProc (INOUT existsInDb BOOLEAN,
IN dbName VARCHAR(50)
IN tableName VARCHAR(50)
IN surnameNew VARCHAR(50)
IN nameNew VARCHAR(50))
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
DECLARE rowSurnameName int;
SET @sqlSel = CONCAT('SELECT COUNT(*) INTO ', rowSurnameName, ' FROM ', dbName, '.', tableName, ' WHERE COGNOME=', surnameNew, ' AND NOME=', nameNew);
PREPARE stmtSel FROM @sqlSel;
EXECUTE stmtSel;
DEALLOCATE PREPARE stmtSel;
IF (rowSurnameName=0) THEN
SET @sqlIns = CONCAT('INSERT INTO ', dbName, '.', tableName, ' (NOME, COGNOME) VALUES (', nameNew, ', ', surnameNew,')');
PREPARE stmtIns FROM @sqlIns;
EXECUTE stmtIns;
DEALLOCATE PREPARE stmtIns;
SELECT false INTO existsInDb;
ELSE SELECT true INTO existsInDb;
END IF;
END
CALL声明是:
SET @dbName = 'DBNAME';
SET @tableName = 'DBTABLE';
SET @surname = 'SURNAME';
SET @name = 'NAME';
PREPARE s FROM 'CALL InsertProc(?,?,?,?,?)';
EXECUTE s USING @existsInDB, @dbName, @tableName, @surname, @name;
SELECT @existsInDB;
错误行是:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1
答案 0 :(得分:0)
几点说明:
您不能在预准备语句中使用局部变量。
C.1 Restrictions on Stored Programs
...
SELECT ... INTO local_var不能用作预处理语句。
...
问题中显示的错误是因为局部变量rowSurnameName
的值为NULL
,请参阅:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> DELIMITER // mysql> CREATE PROCEDURE `InsertProc`() -> BEGIN -> DECLARE `rowSurnameName` INT; -> SELECT `rowSurnameName`; -> SET @`sqlSel` := CONCAT('SELECT COUNT(*) INTO ', `rowSurnameName`); -> SELECT @`sqlSel`; -> END// Query OK, 0 rows affected (0.00 sec) mysql> DELIMITER ; mysql> CALL `InsertProc`; +------------------+ | `rowSurnameName` | +------------------+ | NULL | +------------------+ 1 row in set (0.00 sec) +-----------+ | @`sqlSel` | +-----------+ | NULL | +-----------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
如果您尝试在预准备语句中使用rowSurnameName
局部变量,则会收到错误:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`; Query OK, 0 rows affected (0.00 sec) mysql> DELIMITER // mysql> CREATE PROCEDURE `InsertProc`() -> BEGIN -> DECLARE `rowSurnameName` INT; -> SET @`sqlSel` := CONCAT('SELECT 100 INTO `rowSurnameName`'); -> SELECT @`sqlSel`; -> PREPARE `stmtSel` FROM @`sqlSel`; -> EXECUTE `stmtSel`; -> DEALLOCATE PREPARE `stmtSel`; -> END// Query OK, 0 rows affected (0.00 sec) mysql> DELIMITER ; mysql> CALL `InsertProc`; +----------------------------------+ | @`sqlSel` | +----------------------------------+ | SELECT 100 INTO `rowSurnameName` | +----------------------------------+ 1 row in set (0.00 sec) ERROR 1327 (42000): Undeclared variable: rowSurnameName
您需要在准备好的声明中使用9.4 User-Defined Variables:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`; Query OK, 0 rows affected (0.00 sec) mysql> DELIMITER // mysql> CREATE PROCEDURE `InsertProc`() -> BEGIN -> SET @`sqlSel` := CONCAT('SELECT 100 INTO @`rowSurnameName`'); -> SELECT @`sqlSel`; -> PREPARE `stmtSel` FROM @`sqlSel`; -> EXECUTE `stmtSel`; -> DEALLOCATE PREPARE `stmtSel`; -> IF (@`rowSurnameName` = 0) THEN -> SELECT 'NotExistsInDbAndInsert'; -> ELSE -> SELECT 'existsInDb'; -> END IF; -> END// Query OK, 0 rows affected (0.00 sec) mysql> DELIMITER ; mysql> CALL `InsertProc`; +-----------------------------------+ | @`sqlSel` | +-----------------------------------+ | SELECT 100 INTO @`rowSurnameName` | +-----------------------------------+ 1 row in set (0.00 sec) +------------+ | existsInDb | +------------+ | existsInDb | +------------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)