2017-03-03 57 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