2010-03-10 6 views
1

정수 기본 키로 변환 중이고 정수 값 개수로 새 열 데이터를 시드하는 데 문제가 있습니다.열의 숫자를 채우는 방법?

create table t1 (
    Id uniqueidentifier, 
    NewId int, 
    Data nvarchar(100) 
) 

가 어떻게 결과의 행 # 1에서 숫자의 카운트 기존 행 세트를 업데이트 할 것입니다 :

기존 테이블을 감안할 때?

그래서 :

|id  |NewId  |Data 
------------------------------- 
|ABC  |null  |first 
|DEF  |null  |second 
|GHI  |null  |third 

이 될 것입니다 :

|id  |NewId |Data 
---------------------------- 
|ABC  |1  |first 
|DEF  |2  |second 
|GHI  |3  |third 

를이 내 응용 프로그램 사이에 데이터베이스 왕복을 줄이기 위해 필요한 NHibernate에있는 힐로 기본 키를 사용하여 마이그레이션을위한 IDENTITY는 나를위한 옵션이 아닙니다.

+0

어떤 버전의 SQL Server입니까? 시퀀스가 재설정됩니까? –

+0

SQL Server 2008. 데이터가 채워지면 기본 키 관리에 다른 방법을 사용합니다. 기존 데이터를 한 번만 채우면됩니다. –

답변

4

당신은 row_number 같은 윈도우 기능을 사용할 수 있습니다

update t 
set NewId = sub.rn 
from YourTable t 
join (
    select 
     id 
    , row_number() over (order by id) as rn 
    from YourTable 
) sub on sub.id = t.id 
+0

나는 이걸 시도했는데 @t를 선언해야한다고 말한다. 이 예에서 누락 되었습니까? –

+1

@Michael : 으악, @t는 YourTable이어야합니다. 대답 – Andomar

0

이 작업을 직접 수행하지 말고 단순히 열을 ID로 추가하지 않는 것이 좋습니다.

ALTER TABLE YourTable 
    ADD NewId INT IDENTITY(1,1) 

이렇게하면 문제를 해결할 수 있습니다.

+0

이유는 IDENTITY 기능을 사용하지 않을 이유입니다. 대신 삽입시 데이터베이스 왕복을 피하기 위해 nhibernate를 통해 hilo 알고리즘을 사용할 것입니다. –

+1

이 경우 Row_NUMBER를 사용하는 솔루션이 가장 좋은 방법 일 수 있습니다. –

+0

데이터를 업데이트 한 후 IDENTITY를 제거 할 수 있으므로 Row_Number와 정확히 동일한 기능을 수행하며 과거에도 같은 용도로 사용했습니다. – Rupert

1

하지 그것이 얼마나 효율적 확인을하지만,이 작품 - 바닥

create table t1 (Id uniqueidentifier, 
       NewId int, 
       Data nvarchar(100)) 
create index idx_t1 on t1(data) 

insert into t1 values (newid(), null, 'B') 
insert into t1 values (newid(), null, 'A') 
insert into t1 values (newid(), null, 'F') 
insert into t1 values (newid(), null, 'C') 
insert into t1 values (newid(), null, 'E') 

update t1 
    set [newid]=(select count(*) from t1 as temp where temp.data <= t12.data) 
from t1 as t12 

select * from t1 
1
DECLARE @Id INT 
DECLARE @CurrentRow INT 
SET @CurrentRow = 1 

DECLARE SetIDCursor INSENSITIVE CURSOR FOR 
    SELECT Id 
    FROM t1 
    ORDER BY Id 
    FOR READ ONLY 

OPEN SetIDCursor 

WHILE (0=0) 
    BEGIN 
    FETCH NEXT FROM SetIDCursor 
    INTO @Id 

    IF (@@FETCH_STATUS <> 0) BREAK 

    UPDATE t1 
    SET NewID = @CurrentRow 
    WHERE Id = @Id 

    SET @CurrentRow = @CurrentRow + 1 
    END 

CLOSE SetIDCursor 
DEALLOCATE SetIDCursor 
+0

에서 편집이 예제는 효과가 있었고 30 초가 걸렸습니다. 내가 수락 한 사람은 1 초가 걸렸다. 당신의 도움을 주셔서 감사합니다. –

+1

커서는 정말 최후의 수단이되어야합니다. –

2

사용 ROWNUMBER 근처에 업데이트 명령을 참조하십시오()와 같은 경우에는 다음과 같이 유용합니다.

;WITH SequencedData AS 
(
    SELECT Id, ROW_NUMBER() OVER (ORDER BY Id) Sequence 
    FROM [YourTable] 
) 
UPDATE t 
SET NewId = sd.Sequence 
FROM [YourTable] t 
JOIN SequencedData sd 
    ON sd.Id = t.Id 
2

변수를 사용하여 업데이트되는 모든 행에 대해 변수를 1 씩 증가시킬 수 있습니다.

DECLARE @id INT 
SET @id = 0 

UPDATE TableName 
SET @id = ColumnName = @id + 1 
+0

깨끗하고 우아한 접근 방식을 사용하는 것이 좋습니다. –

관련 문제