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

代码如下:
TOP: BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END; START TRANSACTION; IF LENGTH(ExtUserIds)>0 THEN
DELETE FROM userextinfo WHERE UserID IN(ExtUserIds); -- 删除用户扩展信息
DELETE FROM userinfo WHERE UserID IN(ExtUserIds); -- 删除用户信息
END IF; COMMIT; END
执行存储过程,输入参数“2,3,4”

存储过程执行成功

此时,我们看到表中数据只删除了“老二”的数据


这个问题是由于我们传入的参数“ExtUserIds”是一个字符串,sql语句中的IN只能使用字符串中第一个逗号前的数据,所以在上面的例子中,只删除了2号用户的数据。
正确的方式:
当然,我们可以将字符串“ExtUserIds”按逗号分开,然后循环删除信息,但是这么做会增加不少的逻辑处理。
现在我们不使用“IN”而使用“FIND_IN_SET”,将存储过程修改为:

代码如下:
TOP: BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END; START TRANSACTION; IF LENGTH(ExtUserIds)>0 THEN
DELETE FROM userextinfo WHERE FIND_IN_SET(UserID,ExtUserIds); -- 删除用户扩展信息
DELETE FROM userinfo WHERE FIND_IN_SET(UserID,ExtUserIds); -- 删除用户信息
END IF; COMMIT; END
再次执行存储过程,结果如下:


我们想要删除的3个用户信息全部清除掉了。
至于方法“FIND_IN_SET(str,strlist)”的其他应用场景大家可以自己查阅。
Mysql中使用FIND_IN_SET解决IN条件为字符串时只有第一个数据可用的问题的更多相关文章
- MySQL中的find_in_set()函数使用技巧心得与应用场景总结
Author:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@极客小俊,CSDN官方首发原创文章 企业博客 CSDN.com 个人博 ...
- Mysql中使用find_in_set函数查找字符串
mysql有个表的字段的存储是以逗号分隔的,如domain字段login.s01.yy.com,s01.yy.com,s02.yy.com.现在要查找s01.yy.com这个.我们用like查找好像不 ...
- MySql 中的 FIND_IN_SET 的使用和相关问题
MySql 中的 FIND_IN_SET 的使用和相关问题 QQ 群里有人讨论如果在 category_ids 中打开 12 的分类,而 category_ids 中的 ID 是以 逗号分开的. 使用 ...
- mysql中的find_in_set的使用
原文 http://www.php-note.com/article/detail/383 举个例子来说: 有个文章表里面有个type字段,它存储的是文章类型,有 1头条.2推荐.3热点.4图文... ...
- MySQL中0、'0'作为条件时的区别
一.现象: 今天查询时,某字段x为varchar 可能的值为A B C 0 1 2 3 4 想把0 1 2 3 4的所有数据查出,使用的SQL为 select * from table where x ...
- 关于MySQL中使用LOAD DATA INFILE导入csv文件时的日期格式问题
在使用MySQL时,常常会用到Load Data Infile来导入数据,在遇到Date类型的列时,有时会遇到格式转换的问题: 首先创建一张简单的people表,包含名字,生日,年龄三个字段: mys ...
- 详解MySQL中concat函数的用法(连接字符串)
MySQL中concat函数 使用方法: CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. 注意: 如果所有参数均为非二进制 ...
- mysql中要根据某个逗号分割的字符串关联查询另一张表的数据
首先观察下面的查询 select * from company where f_id in ('210','205','208') select * from company where f_id i ...
- JDBC动态查询MySQL中的表(按条件筛选)
动态查询实现按条件筛选.PreparedStatement 准备语句指定要查询的表头列,.setString()通过赋值指定行,.executeQuery()执行语句 在数据库test里先创建表sch ...
随机推荐
- Codeforce Gym 100015I Identity Checker 暴力
Identity Checker 题目连接: http://codeforces.com/gym/100015/attachments Description You likely have seen ...
- [NOIP 2014复习]第三章:动态规划——NOIP历届真题回想
背包型动态规划 1.Wikioi 1047 邮票面值设计 题目描写叙述 Description 给定一个信封,最多仅仅同意粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定全部的邮票数量都 ...
- iOS开发——网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据
网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一 ...
- 终端I/O之终端窗口的大小
大多数UNIX系统都提供了一种功能,可以对当前终端窗口的大小进行跟踪,在窗口大小发生变化时,使内核通知前台进程组.内核为每个终端和伪终端保存一个winsize结构: Struct winsize { ...
- DIH中添加不同的数据源
需求:从mysql数据库中读取一个知识记录,从记录表中的字段值中获取一个文件路径,读取xml文件,xml文件中可能包含多个文档内容.建立索引. xml文件样例: <?xml version=&q ...
- MySQL(26):事务的隔离级别出现问题之 幻读
1. 幻读 幻读(Phantom Read)又称为虚读,是指在一个事务内两次查询中数据条数不一致,幻读和不重复读有些类型,同样是在两次查询过程中,不同的是,幻读是由于其他事务做了插入记录的操作,导致记 ...
- Android(java)学习笔记63:线程的优先级
1. Java线程的优先级从1到10级别,值越大优先级越高线程默认优先级是5.值越大优先级越高 (1) 继承自Thread类创建线程类: package cn.itcast_04; public cl ...
- Hadoop学习笔记(2) ——解读Hello World
Hadoop学习笔记(2) ——解读Hello World 上一章中,我们把hadoop下载.安装.运行起来,最后还执行了一个Hello world程序,看到了结果.现在我们就来解读一下这个Hello ...
- iOS制作gif动态图
NSMutableArray * array = [NSMutableArray array]; for (int i = 1; i < 6; i++) { NSString * string ...
- codeforces 677C C. Vanya and Label(组合数学+快速幂)
题目链接: C. Vanya and Label time limit per test 1 second memory limit per test 256 megabytes input stan ...