使用游标基于子查询更新数据库的替代方法

时间:2019-04-24 09:52:31

标签: sql sql-server common-table-expression database-cursor

也许这个头衔并没有真正的启发性,但我不能提出一个不太人为的头衔。这是我的问题:

我正在处理具有类似数据的表

id  cId        ver      active
1   100         1       0    
2   100         2       1    
3   100         3       1    
4   200         1       0    
5   200         2       1    
6   300         1       1

对于此表,Id是PK,而cId标识客户端。基本上,我们存储版本控制历史记录。

我要解决的问题是仅针对每个客户端的[ver]最高的最新版本来更新数据库,以将active设置为= 1。 (在示例中,具有cId 100的客户端存在错误)

现在,我设法编写了以下查询,该查询为我提供了要处理的数据

select t.id, t.cId,t.version 
from (select *
      from comp.Clients  a
      where a.ver = (select max(b.ver) from comp.Clients b where a.cId=b.cIdentifier)
    ) t

从那时起,我的解决方案是将该查询插入到游标上,对于游标上的每个记录,我会将表更新为当前记录的active = 0和active = 1。

问题是游标是什么,这里是否有让我表现不错的东西?我对CTE不好,所以我无法提出围绕它的解决方案。实际表有大约1万条记录和大约50个字段。

3 个答案:

答案 0 :(得分:1)

您应该为每个ver找到最后一个CId,然后更新表格

select cId,Max(ver) as MaxVer into #tmpTable from comp.Clients  group by cid

update c
set active = case when t.cId is not null then 1 else 0 end
from comp.Clients c left join #tmpTable t on t.CId=c.CId and t.MaxVer=c.ver

答案 1 :(得分:0)

使用2个更新而不是使用游标。一个将值更新为0,另一个将客户端ID的最新版本设置为1。这足够了。

答案 2 :(得分:0)

使用可更新的CTE:

awk -F'[.= ]' '$0!~/^\[/{print $5"."$6"."$7"."$8,$1,$2"."$3,$1}' d

如果愿意,您可以添加// Find IP, throws alert $.getJSON("http://jsonip.com?callback=?", function (data) { alert(data.ip); }); // My Attempt - Hide menu if IP matches var data = '00.00.00.000'; $('#Menu').each(function() { if (this.data == '00.00.00.000') { $(this).addClass('hide-me'); } 子句以限制要更新的行数:

with toupdate as (
      select c.*,
             max(ver) over (partition by CId) as max_ver
      from comp.Clients c
     )
update toupdate
    set active = (case when max_ver = ver then 1 else 0 end);