2017-03-03 7 views
1

制約の追加時にエラーを回避するために、一意制約を追加する前に、テーブルの「Order」列を更新する必要があります。カーソル行のデータをまだフェッチしていない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 

NEW UNIQUE CONSTRAINT

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

ADD UNIQUE ON ERROR私がしようとしている。このフィールドを更新するには、次のT-SQLコードを実行します条件3はID 3のテーブル行にあります。上記のコードは、ID 3の行をORDERで更新する必要があります。2

しかし、このコードはテーブルの行も更新しません。誰かが、カーソルでまだフェッチしていない行を更新するにはどうすればよいのでしょうか?

+0

をこれは、([XY問題]のように聞こえますhttp://meta.stackexchange.com/a/66378/346416)試行したソリューションの問題ではなく、解決しようとしている問題を共有できますか? – SqlZim

答えて

2

GroupId, [Order], IsOld, IsNew, IsEnabledの各セットに対してOrderをユニークにしようとしているようです。

あなたはあなたがそうのようなcteを使用してスキップすることができ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; 
--*/ 

common table expressionを使用してセットベースの声明でこれを行うことができますについては

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 

を上記の例選択したコードが返されます:

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

関連する問題