2013-07-07 45 views
0

我有一个更新查询在隔离运行时工作,但在存储过程中调用时发生抱怨。插入查询在存储过程中不起作用

mysql> UPDATE `user` SET `password`=COALESCE(NULL, `password`) WHERE `id`=1; 
Query OK, 0 rows affected (0.00 sec) 
Rows matched: 1 Changed: 0 Warnings: 0 


mysql> CALL updateUser(1, NULL, NULL, '1950-02-05', NULL); 
ERROR 1048 (23000): Column 'male' cannot be null 

这里的存储过程

DELIMITER $$ 
CREATE PROCEDURE `updateUser` (IN userId varchar(255), IN password varchar(100), IN male tinyint(1), IN birthday datetime, IN fbId varchar(160)) 
BEGIN 
    START TRANSACTION; 
     UPDATE `user` SET `male` = IFNULL(male, `male`), `password` = IFNULL(password, `password`), `birthday` = IFNULL(birthday, `birthday`) WHERE `id` = userId; 

     IF fbId IS NOT NULL THEN 
      ... 
     END IF; 
    COMMIT; 
END 

我也试图定义使用COALESCE代替IFNULL更新查询,但结果是一样的。有没有人知道发生了什么,我怎么才能让我的程序工作?

+2

我不确定当你的输入参数和他们的目标列有相同的名字时它的行为如何。尝试在过程中将参数重命名为in_male,in_password等,以便从列名中消除歧义。 –

+0

反引号用于引用_identifiers_,参数是标识符。由于参数使用比表列更高的prio来解析,因此它将运行'SET male = IFNULL(NULL,NULL)'。 –

回答

0

问题是存储过程参数与列的名称相同。试试这个:

DELIMITER $$ 
CREATE PROCEDURE `updateUser` (IN p_userId varchar(255), 
           IN p_password varchar(100), 
           IN p_male tinyint(1), 
           IN p_birthday datetime, 
           IN p_fbId varchar(160)) 
BEGIN 
    START TRANSACTION; 
     UPDATE `user` SET `male` = IFNULL(p_male, `male`), 
          `password` = IFNULL(p_password, `password`), 
          `birthday` = IFNULL(p_birthday, `birthday`) 
     WHERE `id` = p_userId; 

     IF fbId IS NOT NULL THEN 
      ... 
     END IF; 
    COMMIT; 
END 

你所得到的误差约male不接受NULL值,因为表达式:

coalesce(male, `male`) 

既是时代指的是存储过程的参数,而不是在表中的列。