2017-09-18 4 views
3

일괄 업데이트로 테이블의 일련 번호를 변경하고 싶습니다. 업데이트에 의해 주문이 포함되지 않았으므로 CTE, with 절을 사용하여 데이터 세트를 작성하고 결과에 대한 업데이트를 발행 했으므로 원하는대로 처리 할 것으로 예상됩니다.
하지만 ID로 업데이트 한 것은 주문한 세트가 아닙니다.
이 업데이트의 문제점은 무엇입니까?cte가 작동하지 않아 주문에 의한 업데이트가 필요한 이유는 무엇입니까?

CREATE TABLE [dbo].[Test](
    [Id] [int] NOT NULL, 
    [Serial] [nvarchar](10) NOT NULL 
) 
insert into Test values 
(1, 1001), 
(2, 1002), 
(3, 1003), 
(4, 1004), 
(5, 1005), 
(6, 1006), 
(7, 1003) 

declare @serial int, @Id int 
set @Id =3 
select @serial = Serial from Test WHERE [email protected] 
declare @new_serial nvarchar(10); 
select @new_serial = cast(@serial as nvarchar(10)); 

;with Records as 
( 
    Select Id, Serial 
    , ROW_NUMBER() over 
    (
     order by serial 
    ) as RN 
    FROM [Test] 
    where Id>@Id 
) 
UPDATE Records set 
    [Serial] = cast(@new_serial as int), 
    @new_serial = cast(@new_serial as int)+1 

여기에 삽입 한 후 존재하는 것입니다 :

여기
+--+----+ 
|1 |1001| 
|2 |1002| 
|3 |1003| 
|4 |1004| 
|5 |1005| 
|6 |1006| 
|7 |1003| 

은 우리가 필요로하는 것입니다 :

+--+----+ 
|1 |1001| 
|2 |1002| 
|3 |1003| 
|4 |1005| 
|5 |1006| 
|6 |1007| 
|7 |1004| 
+0

가 왜 NVARCHAR –

+0

으로 직렬 열이 이유는 무엇 단순히'UPDATE 테스트 SET [시리얼] = cast (int로 Serial) + 1 어디에서 Id> @ Id'? –

+0

레코드는 cte 테이블이며 주어진 예제에서는 유지되지 않습니다. – Jayvee

답변

0

그러나 그것은 나의 명령 세트에 의해 ID로 업데이트합니다. 이 업데이트의 문제점은 무엇입니까?

코드에 주문 세트가 없습니다. CTE가 아니며 "주문"할 수 없습니다.

declare @Test table(
    [Id] [int] NOT NULL, 
    [Serial] [nvarchar](10) NOT NULL 
) 
insert into @Test values 
(1, 1001), 
(2, 1002), 
(3, 1003), 
(4, 1004), 
(5, 1005), 
(6, 1006), 
(7, 1003) 

declare @serial int, @Id int 
set @Id =3 
select @serial = Serial from @Test WHERE [email protected] 
--declare @new_serial nvarchar(10); 
--select @new_serial = cast(@serial as nvarchar(10)); 

;with Records as 
( 
    Select Id, Serial 
    , ROW_NUMBER() over 
    (
     order by serial 
    ) as RN 
    FROM @Test 
    where Id>@Id 
) 
UPDATE Records set 
    [Serial] = cast(cast(@serial as int) + RN as nvarchar(10)) 

select * 
from @test 
+1

사실 TOP를 사용하고 CTE 순서로 업데이트하면 CTE를 주문할 수 있습니다. @RunningTotal = Total = @RunningTotal + Total' – PreQL

+0

@PreQL "주문한"업데이트가없고 "주문한"CTE가 없습니다. 네, 상위를 포함하여 CTE를 "주문"할 수 있지만 CTE가 UNORDERED SET이기 때문에이 주문은 상위 관련 결과에만 영향을 미치고 SELECT COM 결과는 영향을 미치지 않습니다 – sepupic

1

귀하의 업데이트 문이 잘못되었습니다. cte를 갱신하고 값을 지역 변수로 설정합니다. 나는 당신이 업데이트가 행별로 수행 될 것으로 예상하여, 이전 값 +1에 각 행에 Serial의 값을 설정한다고 추측하고있다. 그러나 그것은 SQL의 작동 방식이 아니다.

제공 한 입력에서 원하는 출력을 얻으려면 cte가 필요 없으며 row_number을 사용해야합니다.

DECLARE @Id int = 3 
UPDATE Test 
SET [Serial] = cast(Serial as int) + 1 
WHERE Id > @Id 

확인 :

SELECT Id, Serial 
FROM Test 

결과 : 당신은 단순히이 작업을 수행 할 수 있습니다

Id Serial 
1 1001 
2 1002 
3 1003 
4 1005 
5 1006 
6 1007 
7 1004 

See a live demo on rextster.

1

먼저 테이블에 행 수를 셀 수 있습니다 :

당신은 당신이하지 않으면, 당신의 코드가 전혀 ROW_NUMBER()에 의존하지 않는, 당신의 업데이트에 계산 된 RN를 사용한다 및 변수를 사용하거나 전체 테이블을 선택하여 TOP의 큰 숫자를 선택하고 주문이하여 시리얼 :

;with Records as 
( 
    Select TOP 100000 
     Id 
     , Serial 
    FROM [Test] 
    where Id>@Id 
    ORDER BY Serial 
)