2010-05-06 60 views
2

我想設置一些id的數據庫中id列是標識的一堆行。IDENTITY_INSERT在光標內部不允許插入標識

我創建了一個遊標循環遍歷行,並用遞增負數(-1,-2,-3等)更新id。

當我只更新了一行打開IDENTITY_INSERT它工作正常,但只要我嘗試在遊標中使用它,它會引發以下錯誤。

Msg 8102,Level 16,State 1,Line 22 無法更新標識列'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 

有誰知道我在做什麼錯?

回答

6

反正你不需要光標。忽略它們是標識列這樣的事情會在派生表的工作,那麼你可以加入到它更新的基於集合的方式都行

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

這如果你最終設定的身份可能仍然是一個有用的方法插上然後把它們插入所有類似的,然後刪除那些WHERE myRowId> 17095(按順序!)在交易

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,正是我在想,+10000更多,如果我可以,使用一組而不是遊標! – 2010-05-06 11:59:46

+0

謝謝,正是我需要的。 – 2010-05-06 12:40:36