2017-03-03 3 views
1

제약 조건을 추가 할 때 오류가 발생하지 않도록 고유 제약 조건을 추가하기 전에 테이블의 "Order"열을 업데이트해야합니다. CONSTRAINT아직 가져온 커서 행의 데이터를 업데이트하지 않았습니다. SQL Server

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

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

새로운 고유 한 UNIQUE를 ADD ON 오류 :

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 

테이블 데이터 : 나는 다음과 T-SQL 코드를 할 노력하고있어이 필드를 업데이트하려면 ID 행이있는 테이블 행에서 제한이 발생합니다. 위의 코드는 ID가 3 인 행을 ORDER로 업데이트해야합니다. 2

그러나이 코드는 테이블의 행을 업데이트하지 않습니다. 누군가 내가 커서에서 아직 가져 오지 않은 행을 어떻게 업데이트 할 수 있는지 알고 있습니까?

+0

이것은 [XY 문제] 같은 소리 (http://meta.stackexchange.com/a/66378/346416) 시도한 솔루션의 문제 대신 해결하려는 문제를 공유 할 수 있습니까? – SqlZim

답변

2

GroupId, [Order], IsOld, IsNew, IsEnabled 각각에 대해 Order을 고유하게 만드는 것처럼 보입니다.

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 

경우 :

당신은 당신은 cte과 같이를 사용하여 건너 뛸 수있는 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; 
--*/ 

를 사용하여 설정을 기반으로 문을 사용하여이 작업을 수행 할 수 있습니다 위의 주어진 예제 , 선택 코드가 반환 :

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