2014-06-15 79 views
1

這些存儲過程都編譯我的MySQL服務器73年5月1日:爲什麼傳入存儲過程的參數會導致MySQL錯誤1267?

delimiter $$ 
CREATE PROCEDURE get_admins() 
    BEGIN 
      SELECT * 
      FROM Accounts 
       INNER JOIN LINK_Account_Status ON Accounts.account_id=LINK_Account_Status.account_id 
        AND LINK_Account_Status.active_ind=1 
      WHERE Accounts.active_ind=1 
       AND Accounts.`type`='admin'; 
    END $$ 
delimiter ; 

delimiter $$ 
CREATE PROCEDURE get_admins2(
    IN p_type varchar(50) 
) 
    BEGIN 
      SELECT * 
      FROM Accounts 
       INNER JOIN LINK_Account_Status ON Accounts.account_id=LINK_Account_Status.account_id 
        AND LINK_Account_Status.active_ind=1 
      WHERE Accounts.active_ind=1 
       AND Accounts.`type`=p_type; 
    END $$ 
delimiter ; 

執行CALL get_admins();返回結果我的期望。

執行CALL get_admins2('admin');錯誤:

錯誤代碼:1267歸類的非法混合物(utf8_general_ci,IMPLICIT) 和(utf8_unicode_ci,隱含的)操作 '='

細心的響應將注意兩個結果查詢之間沒有功能差異。我仔細檢查了Accounts.type確實是varchar(50)(即使它不幸命名)。

Sam Hill在這裏發生了什麼?

回答

2

你需要在你的WHERE條件使用COLLATE解決這個像下面

delimiter $$ 
CREATE PROCEDURE get_admins2(
    IN p_type varchar(50) 
) 
    BEGIN 
      SELECT * 
      FROM Accounts 
       INNER JOIN LINK_Account_Status ON 
Accounts.account_id=LINK_Account_Status.account_id 
        AND LINK_Account_Status.active_ind=1 
      WHERE Accounts.active_ind=1 
       AND Accounts.`type`=p_type COLLATE utf8_general_ci; /* <-- Here */ 
    END $$ 
delimiter ; 

可以在參數聲明本身("As of [MySQL] 5.5.3, COLLATE can be used...")等,以及添加歸類:

delimiter $$ 
CREATE PROCEDURE get_admins2(
    IN p_type varchar(50) COLLATE utf8_general_ci <-- Here 

.....<rest of the code here>..... 

編輯:

經過一番搜索,我發現,這即使表具有相同的排序規則,如果您的列有不同的排序規則,則可能會出現問題。請參見下面的MySQL論壇發帖

http://forums.mysql.com/read.php?103,265345,265579

+1

「參數類型和函數返回類型可以聲明爲使用任何有效的數據類型,不同的是COLLATE屬性不能使用。」 http://dev.mysql.com/doc/refman/5.1/en/create-procedure.html –

+2

@JeromyFrench,是;我錯過了你正在使用5.1。*。然後你可以在'WHERE'條件下使用它,但是在MySQL 5.6或更高版本中,你可以在參數聲明中使用'collat​​e';就像你已經編輯過的一樣。是的,謝謝你。 – Rahul

+0

謝謝你指點我在正確的方向。 –