2010-03-10 7 views
1

Je suis en train de convertir en une clé primaire entière et j'ai du mal à ensemencer les nouvelles données de colonne avec un nombre de nombres entiers.Comment remplir une colonne avec un nombre de chiffres?

Étant donnée une table existante:

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

Comment pourrais-je mettre à jour les lignes existantes avec un compte de nombres de 1 à nombre de lignes dans le jeu de résultats?

Alors:

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

deviendrait:

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

Ceci est pour une migration vers l'aide d'une clé primaire hilo avec NHibernate, qui est nécessaire pour réduire les allers-retours de la base de données avec entre ma demande et les niveaux de base de données, donc IDENTITY n'est pas une option pour moi.

+0

Quelle version de SQL Server? Est-ce que la séquence a été réinitialisée? –

+0

SQL Server 2008. Une fois les données remplies, j'utiliserai une méthode différente pour gérer la clé primaire. J'ai juste besoin de remplir les données existantes une fois. –

Répondre

4

Vous pouvez utiliser une fonction de fenêtrage comme 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

J'ai essayé cela et il est dit que je dois déclarer @t. Cela manque-t-il à l'exemple? –

+1

@Michael: Oups, @t devrait être YourTable. Édité dans la réponse – Andomar

0

Plutôt que d'essayer de le faire vous-même, pourquoi ne pas simplement ajouter la colonne comme identité.

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

Ceci prendra soin de vous pour vous.

+0

La raison pour laquelle je ne vais pas utiliser la fonctionnalité IDENTITY. Au lieu de cela, je vais utiliser un algorithme hilo via nhibernate pour éviter les allers-retours de base de données sur les insertions. –

+1

Dans ce cas, une solution utilisant Row_NUMBER pourrait être la meilleure solution. –

+0

Vous pouvez supprimer l'IDENTITY après la mise à jour des données, de sorte que cette fonction remplit exactement la même fonction que Row_Number et que je l'ai utilisée dans le passé dans le même but. – Rupert

1

ne sais pas comment il est efficace, mais cela fonctionne - voir la commande de mise à jour près du fond

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

Cet exemple a fonctionné et a pris 30 secondes. Celui que j'ai accepté a pris 1 seconde, donc j'ai marqué cela comme étant répondu. Merci de votre aide. –

+1

Cursors devrait vraiment être un dernier recours –

2

utilisation RowNumber(), il est bon pour des choses comme ceci:

;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

Vous pouvez utiliser une variable et l'incrémenter de 1 pour chaque ligne mise à jour.

DECLARE @id INT 
SET @id = 0 

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

bon avec une approche propre et élégante. –

Questions connexes