在具有out参数的调用存储过程中,Null附近的Mysql错误#1064

时间:2017-08-06 10:06:04

标签: mysql stored-procedures mysql-error-1064

我对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 

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)