更新尚未获取的游标行中的数据 sql 服务器

Update data in a cursor row not yet fetched sql server

在添加唯一约束之前,我需要更新 table 的 "Order" 列,以避免在添加约束时出错。要更新此字段,我正在尝试执行以下 T-SQL 代码:

DECLARE c_x CURSOR FOR
SELECT ID, ISOLD, ISNEW, GROUPID, ORDER, ISENABLED
FROM mytable

OPEN c_x;
FETCH NEXT FROM c_x INTO @ID, @ISOLD, @ISNEW, @GROUPID, @ORDER, @ISENABLED;

WHILE @@FETCH_STATUS = 0  
BEGIN  
SELECT @SUMOFROWS = COUNT(*) FROM mytable
    WHERE ISOLD = @ISOLD
        AND ISNEW = @ISNEW
        AND GROUPID = @GROUPID
        AND ORDER = @ORDER
        AND ISENABLED = @ISENABLED;


IF @SUMOFROWS > 1
        BEGIN
            UPDATE mytable
            SET ORDER = ORDER+ 1
            WHERE ISOLD =  @ISOLD 
            AND ISNEW =  @ISNEW 
            AND GROUPID =  @GROUPID 
            AND ISENABLED =  @ISENABLED 
            AND ORDER >= @ORDER 
            AND ID <> @ID

        END

    FETCH NEXT FROM CURSOR_TIPOS_AGENDA INTO @ID, @ISOLD, @ISNEW, @GROUPID, @ORDER, @ISENABLED
END 

Table数据:

ID   ISOLD  ISNEW  GROUPID ORDER ISENABLED
1    1      0      500     1      1
2    0      0      500     1      1
3    0      0      500     1      1

新的唯一约束

CREATE UNIQUE NONCLUSTERED INDEX [XAK1_mytable] ON mytable([ORDER], [ISENABLED], [ISOLD`], [ISNEW], [GROUPID])

添加唯一约束的错误发生在 ID 为 3 的 TABLE 行中。上面的代码应使用订单 2

更新 ID 为 3 的行

但是此代码也不会更新 table 的行。有人知道如何更新游标中尚未获取的行吗?

您似乎在尝试使每组 GroupId, [Order], IsOld, IsNew, IsEnabledOrder 独一无二。

您可以通过使用 common table expression with row_number()

的基于集合的语句来执行此操作
;with cte as (
  select 
      Id
    , IsOld
    , IsNew
    , GroupId
    , [Order]
    , IsEnabled
    , rn = row_number() over (
        partition by GroupId, [Order], IsOld, IsNew, IsEnabled
        order by [Order]
        ) - 1
  from t
  )
--Preview: 
--/*
select *, NewOrder = [Order] + rn
from cte
where rn > 0
--*/
/*
--Update
update cte 
  set [Order] = [Order] + rn
where rn > 0;
--*/

您可以像这样跳过使用 cte

update cte
  set [Order] = [Order] + rn
from (
  select *
    , rn = row_number() over (
        partition by GroupId, [Order], IsOld, IsNew, IsEnabled
        order by [Order]
        ) - 1
  from t
  ) as cte
where rn > 0

对于上面给出的示例,select 代码将 return:

+----+-------+-------+---------+-------+-----------+----+----------+
| Id | IsOld | IsNew | GroupId | Order | IsEnabled | rn | NewOrder |
+----+-------+-------+---------+-------+-----------+----+----------+
|  3 |     0 |     0 |     500 |     1 |         1 |  1 |        2 |
+----+-------+-------+---------+-------+-----------+----+----------+

在 运行 更新后,table 看起来像这样:

+----+-------+-------+---------+-------+-----------+
| Id | IsOld | IsNew | GroupId | Order | IsEnabled |
+----+-------+-------+---------+-------+-----------+
|  1 |     1 |     0 |     500 |     1 |         1 |
|  2 |     0 |     0 |     500 |     1 |         1 |
|  3 |     0 |     0 |     500 |     2 |         1 |
+----+-------+-------+---------+-------+-----------+

测试设置:http://rextester.com/XJAUJ47591