where条件为两个的怎么批量删除?

-一个大坑 2018-03-21 04:18:27
写了一个for循环删除,领导觉得慢了,要改成批量删除。要怎么写?
where id in ('001','002') and room in ('A201','A202')这样明显不行
...全文
1201 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
-一个大坑 2018-03-22
  • 打赏
  • 举报
回复
引用 27 楼 xomix 的回复:
还有就是不要看单条拼接有效率优势,那是理想情况,也就是两组操作都没有遇到任何事物锁等数据库内效率占用的情况。 举个栗子: 如果你使用了单条拼接,为了方便错误回滚使用了事物,这时候你的删除工作就由最初的每条一次的行锁转变为表锁,这里面损失多少资源就不用我细说了吧? 而or拼接就只是先查询后行锁,而且还不用事物就可以保证一致性。 所以具体怎么做,还是要看你自己的业务环境自己定义。
我写循环删除就是因为不用一起删。这样就用delete拼吧,感觉简单一些 最大条数是1000,string最长65534字节。我写个控制500删一次
  • 打赏
  • 举报
回复
还有就是不要看单条拼接有效率优势,那是理想情况,也就是两组操作都没有遇到任何事物锁等数据库内效率占用的情况。 举个栗子: 如果你使用了单条拼接,为了方便错误回滚使用了事物,这时候你的删除工作就由最初的每条一次的行锁转变为表锁,这里面损失多少资源就不用我细说了吧? 而or拼接就只是先查询后行锁,而且还不用事物就可以保证一致性。 所以具体怎么做,还是要看你自己的业务环境自己定义。
  • 打赏
  • 举报
回复
这里探讨一下过程吧,你如果使用拼接语句,中间拼接的字符串出错,将会导致出现删除了一半剩下的没删除的情况,你如果用 or连接就不会有这种情况,但是不论哪种情况你能链接的语句数量都有限,or拼接能多拼几次。 然后说说效率 单句拼接,是每条扫描整表获取要删除的行列表,执行删除,反复执行每句语句。 or拼接,是每个or条件扫描整表获取要删除的行,反复拼接全部要删除的行列表,执行删除。 所以效率上差不多,但是考虑单条执行时每次删除完成后下一条语句要扫描的表的行数更少(你删掉了一些嘛),所以如果单条执行的时候有一个条件删除了较多数据后单挑拼接的优势会很明显。 但是……现在的数据库服务器都有缓存等服务器端优化了,所以效率上的差异,真的很小,没有什么好担心的,更多的担心放在事物、最大条数、最长语句这些上吧。
  • 打赏
  • 举报
回复
引用 23 楼 happy4944 的回复:
[quote=引用 21 楼 hanjun0612 的回复:] 那你直接 string sql="delete dbo.Web_CardPurview where id=101 and room='A101';delete dbo.Web_CardPurview where id=102 and room='A102'" 反正也是批处理的。 至于这个sql肯定是for拼接出来的
string sql="delete dbo.Web_CardPurview where id=101 and room='A101';delete dbo.Web_CardPurview where id=102 and room='A102'" 和 string sql="delete dbo.Web_CardPurview where (id=101 and room='A101') or (id=102 and room='A102')" 效率相比哪个好? [/quote] 两个效率差不多,都是两次全表扫描。其实你做临时表也差不多。
正怒月神 版主 2018-03-22
  • 打赏
  • 举报
回复
你直接试试看,我目测 string sql="delete dbo.Web_CardPurview where id=101 and room='A101';delete dbo.Web_CardPurview where id=102 and room='A102'" 比较快
-一个大坑 2018-03-22
  • 打赏
  • 举报
回复
引用 21 楼 hanjun0612 的回复:
那你直接 string sql="delete dbo.Web_CardPurview where id=101 and room='A101';delete dbo.Web_CardPurview where id=102 and room='A102'" 反正也是批处理的。 至于这个sql肯定是for拼接出来的
string sql="delete dbo.Web_CardPurview where id=101 and room='A101';delete dbo.Web_CardPurview where id=102 and room='A102'" 和 string sql="delete dbo.Web_CardPurview where (id=101 and room='A101') or (id=102 and room='A102')" 效率相比哪个好?
Jason_Mao1 2018-03-22
  • 打赏
  • 举报
回复
我个人认为 你这个 应该可以有两个地方可以优化,1 sql 的删除条件 。2 你可以批量执行删除SQL 语句啊 为什么要循环删除 ?对吧。比如说 500 条SQL 执行一次。这样的话肯定是要比你循环快很多 。
正怒月神 版主 2018-03-22
  • 打赏
  • 举报
回复
引用 13 楼 happy4944 的回复:
[quote=引用 9 楼 hanjun0612 的回复:] 你至少要告诉我们,你是怎么个规则删除啊。 你的sql语句意思,只是说 id在 001-002并且 room在A201-A202 既然你的sql语句执行不符合预期,那就说明你的需求不是这个描述。 请给出你的描述再说吧
我是准备一次删除id='001' and room='A201'和id='002' and room ='A202'这两条数据 现在就是一直for循环调用这个方法删除数据,现在要一次删

public static bool DeleteAuth(string strID, string strRoom)
     {
       try{
            string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["ECSORUSP"].ConnectionString;
            Hashtable  parameters = new Hashtable();
            string sSQL = "delete from dbo.Web_CardPurview where id=@id and room=@room";            
            parameters.Clear();
            parameters.Add("@id", strID);
            parameters.Add("@room", strroom);
             MSDataAccessTool.DataAccessMSSQL.ExecuteSQL(strConn, sSQL);
            return true;
      }
     catch
    {
      return fales;
     }
  }
[/quote] 那你直接 string sql="delete dbo.Web_CardPurview where id=101 and room='A101';delete dbo.Web_CardPurview where id=102 and room='A102'" 反正也是批处理的。 至于这个sql肯定是for拼接出来的
sherl1ock 2018-03-22
  • 打赏
  • 举报
回复
具体问题具体讨论,你这个写法是id在001和002之间而且room在A201和A202之间的吗? 那不是写成 where (id='001' or id='002') and (room ='A201' or room ='A202')
-一个大坑 2018-03-22
  • 打赏
  • 举报
回复
引用 8 楼 xomix 的回复:
拼接or语句是有一定的劣势的,每一段 or 就是一次全表搜索。 所以如果拼接的or语句超过20行或者数据库数量超过10w的话,建议分步骤临时表操作后用主键匹配删除数据。
我如果循环了几百或几千个or,string 语句就会很长了,这样后面循环继续加长string语句是不是也影响性能 分步骤临时表操作后用主键匹配删除数据 这个怎么操作?
-一个大坑 2018-03-22
  • 打赏
  • 举报
回复
引用 15 楼 sp1234 的回复:
问一下你们的领导,更高层次的代码该如何设计。既然你明知道这个where语句的条件是 (a and b) or (c and d)形式,那么你贴出的
public static bool DeleteAuth(string strID, string strRoom)
根本就该扔掉。如果高层一点的东西自己不会设计,建议请求你的领导重新进行程序设计知识培训。你贴的代码与出问题的设计根本不是一个层次的代码(根本不是在这个层面去修改代码),这已经说明了更深的问题。
没有培训程序设计知识,就是先带我改一些bug,然后照着以前的程序写代码。而且网上那些教程一般也是代码方面的讲解,很少看到程序设计方面的
-一个大坑 2018-03-22
  • 打赏
  • 举报
回复
引用 17 楼 sp1234 的回复:
[quote=引用 4 楼 xomix 的回复:] 这样即可 要是还是觉得慢,那么需要从实际问题分析出发,不能一味更换技术方案
同意。 实际上我觉得合并成为 x1 or x2 or x3..... 这样的形式,并不会提高多少速度。问题并不是在于此。当然合并 sql 一定会比不合并要“快一点”,这可能是感觉不到地那么一点“性能”,但是麻烦了许多,需要在高层重新设计。所以搞明白索引、范式等等设计才是基础,“领导”估计也就是习惯于随便找一个并不重要的(但是麻烦的)的东西让你反复乱实验。[/quote] 我也想过重写代码,但是以前的都是for循环的,我也不知道更好的方法
qq_21607835 2018-03-22
  • 打赏
  • 举报
回复
引用 33 楼 u014508939 的回复:
我昨天就用到了批量删除根据2个值进行删除 用的是mybatis 楼主参考下 <delete id="deleteBatch" parameterType="java.util.List"> delete from md_prsnl_ent where (PRSNLID,ENTID) in <foreach item="item" index="index" collection="list" separator="," open="(" close=")"> (#{item.prsnlid},#{item.entid}) </foreach》 </delete>
可以啊~
晨曦遇晓 2018-03-22
  • 打赏
  • 举报
回复
我昨天就用到了批量删除根据2个值进行删除 用的是mybatis 楼主参考下 <delete id="deleteBatch" parameterType="java.util.List"> delete from md_prsnl_ent where (PRSNLID,ENTID) in <foreach item="item" index="index" collection="list" separator="," open="(" close=")"> (#{item.prsnlid},#{item.entid}) </foreach> </delete>
a1009138981 2018-03-22
  • 打赏
  • 举报
回复
谢谢各位大神
  • 打赏
  • 举报
回复
引用 4 楼 xomix 的回复:
这样即可 要是还是觉得慢,那么需要从实际问题分析出发,不能一味更换技术方案
同意。 实际上我觉得合并成为 x1 or x2 or x3..... 这样的形式,并不会提高多少速度。问题并不是在于此。当然合并 sql 一定会比不合并要“快一点”,这可能是感觉不到地那么一点“性能”,但是麻烦了许多,需要在高层重新设计。所以搞明白索引、范式等等设计才是基础,“领导”估计也就是习惯于随便找一个并不重要的(但是麻烦的)的东西让你反复乱实验。
  • 打赏
  • 举报
回复
引用 14 楼 happy4944 的回复:
每次or就是一次全表搜索这样也不快,一般是几百条或几千条数据 建议分步骤临时表操作后用主键匹配删除数据 这个没太明白
跟 or 没有直接关系。你用 or 来连接的多个条件部分,分别都使用到数据库表的索引,所以写 or 没有任何性能问题。 它主要是把你分多次(比如说10次)发送给数据库的查询,合并到一个sql 会话中一次去发送给数据库系统去执行。所以你没有这个层面的代码设计,纠结于下一层方法,所以始终没有搞对该设计的地方。
  • 打赏
  • 举报
回复
问一下你们的领导,更高层次的代码该如何设计。既然你明知道这个where语句的条件是 (a and b) or (c and d)形式,那么你贴出的
public static bool DeleteAuth(string strID, string strRoom)
根本就该扔掉。如果高层一点的东西自己不会设计,建议请求你的领导重新进行程序设计知识培训。你贴的代码与出问题的设计根本不是一个层次的代码(根本不是在这个层面去修改代码),这已经说明了更深的问题。
引用 13 楼 happy4944 的回复:
我是准备一次删除id='001' and room='A201'和id='002' and room ='A202'这两条数据 现在就是一直for循环调用这个方法删除数据,现在要一次删

public static bool DeleteAuth(string strID, string strRoom)
     {
       try{
            string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["ECSORUSP"].ConnectionString;
            Hashtable  parameters = new Hashtable();
            string sSQL = "delete from dbo.Web_CardPurview where id=@id and room=@room";            
            parameters.Clear();
            parameters.Add("@id", strID);
            parameters.Add("@room", strroom);
             MSDataAccessTool.DataAccessMSSQL.ExecuteSQL(strConn, sSQL);
            return true;
      }
     catch
    {
      return fales;
     }
  }
-一个大坑 2018-03-21
  • 打赏
  • 举报
回复
引用 8 楼 xomix 的回复:
[quote=引用 楼主 happy4944 的回复:] 写了一个for循环删除,领导觉得慢了,要改成批量删除。要怎么写? where id in ('001','002') and room in ('A201','A202')这样明显不行
具体问题具体讨论,你这个写法是id在001和002之间而且room在A201和A202之间的吗? 那不是写成 where (id='001' or id='002') and (room ='A201' or room ='A202') 这样即可 要是还是觉得慢,那么需要从实际问题分析出发,不能一味更换技术方案
引用 7 楼 happy4944 的回复:
[quote=引用 4 楼 xomix 的回复:] [quote=引用 楼主 happy4944 的回复:] 写了一个for循环删除,领导觉得慢了,要改成批量删除。要怎么写? where id in ('001','002') and room in ('A201','A202')这样明显不行
具体问题具体讨论,你这个写法是id在001和002之间而且room在A201和A202之间的吗? 那不是写成 where (id='001' or id='002') and (room ='A201' or room ='A202') 这样即可 要是还是觉得慢,那么需要从实际问题分析出发,不能一味更换技术方案[/quote] 看到你写的想到应该可以这么写 where (id='001' and room='A201') or (id='002' and room ='A202')[/quote] 拼接or语句是有一定的劣势的,每一段 or 就是一次全表搜索。 所以如果拼接的or语句超过20行或者数据库数量超过10w的话,建议分步骤临时表操作后用主键匹配删除数据。[/quote] 每次or就是一次全表搜索这样也不快,一般是几百条或几千条数据 建议分步骤临时表操作后用主键匹配删除数据 这个没太明白
-一个大坑 2018-03-21
  • 打赏
  • 举报
回复
引用 9 楼 hanjun0612 的回复:
你至少要告诉我们,你是怎么个规则删除啊。 你的sql语句意思,只是说 id在 001-002并且 room在A201-A202 既然你的sql语句执行不符合预期,那就说明你的需求不是这个描述。 请给出你的描述再说吧
我是准备一次删除id='001' and room='A201'和id='002' and room ='A202'这两条数据 现在就是一直for循环调用这个方法删除数据,现在要一次删

public static bool DeleteAuth(string strID, string strRoom)
     {
       try{
            string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["ECSORUSP"].ConnectionString;
            Hashtable  parameters = new Hashtable();
            string sSQL = "delete from dbo.Web_CardPurview where id=@id and room=@room";            
            parameters.Clear();
            parameters.Add("@id", strID);
            parameters.Add("@room", strroom);
             MSDataAccessTool.DataAccessMSSQL.ExecuteSQL(strConn, sSQL);
            return true;
      }
     catch
    {
      return fales;
     }
  }
加载更多回复(12)

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧