Mysql中使用FIND_IN_SET解決IN條件為字符串時只有第一個數據可用的問題


今天在使用Mysql的存儲過程處理數據的批量刪除時,遇到了WHERE條件中使用IN(strlist)時(strlist為逗號分隔的字符串),只有strlist的第一個元素才有效的問題,現在將問題和解決方法做下記錄。

 

我們首先創建兩張表userinfo(用戶信息表)和userextinfo(用戶擴展信息表),其中userextinfo表的UserID字段為外鍵對應userinfo表中的UserID字段

用戶信息表userinfo

初始數據

 

用戶擴展信息表userextinfo

初始數據

現在表中有6個用戶的信息,倘若我們現在需要根據用戶ID刪除用戶“老二”、“老三”和“老四”的數據,則需要先刪除userextinfo表中數據然后再刪除userinfo表中的數據。若在代碼中分別對三個用戶執行sql語句,先后刪除userextinfo和userinfo的信息,可以完成我們的目的。但是,當我們一次需要刪除的用戶越多時,在數據庫連接上的開銷就會增多。所以,我們現在可以采用存儲過程,用一次數據庫連接來完成這個操作。

 

錯誤的方式:

我們創建存儲過程P_User_Del

代碼如下:

 1 TOP: BEGIN
 2 DECLARE EXIT HANDLER FOR SQLEXCEPTION
 3 BEGIN
 4     ROLLBACK;        
 5 END;
 6     
 7 START TRANSACTION;
 8     
 9     IF LENGTH(ExtUserIds)>0 THEN
10       DELETE FROM userextinfo WHERE UserID IN(ExtUserIds); -- 刪除用戶擴展信息
11       DELETE FROM userinfo WHERE UserID IN(ExtUserIds); -- 刪除用戶信息
12     END IF;            
13 
14 COMMIT;    
15 
16 END

執行存儲過程,輸入參數“2,3,4”

存儲過程執行成功

此時,我們看到表中數據只刪除了“老二”的數據

這個問題是由於我們傳入的參數“ExtUserIds”是一個字符串,sql語句中的IN只能使用字符串中第一個逗號前的數據,所以在上面的例子中,只刪除了2號用戶的數據。

 

正確的方式:

當然,我們可以將字符串“ExtUserIds”按逗號分開,然后循環刪除信息,但是這么做會增加不少的邏輯處理。

現在我們不使用“IN”而使用“FIND_IN_SET”,將存儲過程修改為:

代碼如下:

 1 TOP: BEGIN
 2 DECLARE EXIT HANDLER FOR SQLEXCEPTION
 3 BEGIN
 4     ROLLBACK;        
 5 END;
 6     
 7 START TRANSACTION;
 8     
 9     IF LENGTH(ExtUserIds)>0 THEN
10       DELETE FROM userextinfo WHERE FIND_IN_SET(UserID,ExtUserIds); -- 刪除用戶擴展信息
11       DELETE FROM userinfo WHERE FIND_IN_SET(UserID,ExtUserIds); -- 刪除用戶信息
12     END IF;            
13 
14 COMMIT;    
15 
16 END

再次執行存儲過程,結果如下:

我們想要刪除的3個用戶信息全部清除掉了。

至於方法“FIND_IN_SET(str,strlist)”的其他應用場景大家可以自己查閱。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM