2013-07-07 42 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`) 

既是時代指的是存儲過程的參數,而不是在表中的列。