2017-03-03 65 views
1

我需要在添加唯一约束之前更新表的“Order”列,以避免添加约束时出错。要更新这个领域我试着做下面的T-SQL代码:更新尚未提取的游标行中的数据sql server

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 

表数据:

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

THE NEW唯一约束

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

中添加的独特ERROR约束在表行中发生,ID为3.上面的代码应该用ID 3的顺序更新行2

但是,这段代码并不会更新表的行。有人知道如何更新我尚未在光标中获取的行?

+0

这听起来像一个[XY问题( http://meta.stackexchange.com/a/66378/346416)您可以分享您尝试解决的问题,而不是尝试解决方案的问题吗? – SqlZim

回答

2

它看起来像你正在努力使Order独特的每一套GroupId, [Order], IsOld, IsNew, IsEnabled

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 

为:

您可以使用common table expressionrow_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像这样跳过了一套基于语句做到这一点上面给出的例子,选择代码将返回:

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

后运行更新,该表是这样的:

+----+-------+-------+---------+-------+-----------+ 
| 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