2010-05-06 2 views
2

J'essaie de définir des ID pour un groupe de lignes dans une base de données où la colonne id est une identité.IDENTITY_INSERT ON à l'intérieur du curseur n'autorise pas l'ID inséré

J'ai créé un curseur pour faire défiler les lignes et mettre à jour les identifiants en incrémentant les nombres négatifs (-1, -2, -3, etc.).

Lorsque j'ai mis à jour une seule ligne en activant IDENTITY_INSERT, cela a bien fonctionné, mais dès que j'essaie de l'utiliser dans un curseur, il renvoie l'erreur suivante. Msg 8102, niveau 16, état 1, ligne 22 Impossible de mettre à jour la colonne d'identité 'myRowID'.

DECLARE @MinId INT; 
SET @MinId = (SELECT MIN(myRowId) FROM myTable)-1; 

DECLARE myCursor CURSOR 
FOR 
SELECT myRowId 
FROM dbo.myTable 
WHERE myRowId > 17095 

OPEN myCursor 
DECLARE @myRowId INT 

FETCH NEXT FROM myCursor INTO @myRowId 
WHILE (@@FETCH_STATUS <> -1) 
BEGIN 

SET IDENTITY_INSERT dbo.myTable ON; 

--UPDATE dbo.myTable 
--SET myRowId = @MinId 
--WHERE myRowId = @myRowId; 

PRINT (N'ID: ' + CAST(@myRowId AS VARCHAR(10)) + N' NewID: ' + CAST(@MinId AS VARCHAR(4))); 
SET @MinId = @MinId - 1; 
FETCH NEXT FROM myCursor INTO @myRowId 
END 

CLOSE myCursor 
DEALLOCATE myCursor 
GO 
SET IDENTITY_INSERT dbo.myTable OFF; 
GO 

Est-ce que quelqu'un sait ce que je fais mal?

Répondre

6

De toute façon, vous n'avez pas besoin de curseur pour cela. Ignorant qu'ils sont des colonnes d'identité quelque chose comme cela fonctionnerait dans une table dérivée alors vous pouvez joindre sur elle pour mettre à jour toutes les lignes d'un moyen basé

select 0-row_number() over(order by myRowId asc) as myRowId,* 
from dbo.myTable 
WHERE myRowId > 17095 

Cela pourrait encore être une approche utile si vous finissez par l'identité mise insérer ensuite les insérer sur tous comme ça puis supprimer ceux où myRowId> 17095 (dans cet ordre!) dans une transaction

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

BEGIN TRAN 
SET IDENTITY_INSERT dbo.myTable ON; 

INSERT INTO dbo.myTable 
SELECT 0-row_number() OVER(ORDER BY myRowId ASC) AS myRowId, OtherColumns 
FROM dbo.myTable 
WHERE myRowId > 17095 

DELETE FROM dbo.myTable WHERE myRowId > 17095 

SET IDENTITY_INSERT dbo.myTable OFF; 
COMMIT 
+0

+1, exactement ce que je pensais, plus si je +10000 pouvais, pour utiliser un ensemble approche basée et pas un curseur !!! –

+0

Merci, juste ce dont j'avais besoin. –

Questions connexes