IDENTITY_INSERT ON внутри курсора не позволяет вставленный идентификатор - PullRequest
2 голосов
/ 06 мая 2010

Я пытаюсь установить некоторые идентификаторы для группы строк в базе данных, где столбец идентификатора является идентификатором.

Я создал курсор для циклического перемещения по строкам и обновления идентификаторов с увеличением отрицательных чисел (-1, -2, -3 и т. Д.).

Когда я обновил только одну строку, включив IDENTITY_INSERT, он работал нормально, но как только я пытаюсь использовать его в курсоре, он выдает следующую ошибку.

Сообщение 8102, уровень 16, состояние 1, строка 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

Кто-нибудь знает, что я делаю не так?

1 Ответ

6 голосов
/ 06 мая 2010

Вам не понадобится курсор для этого в любом случае. Игнорируя, что они являются столбцами идентификаторов, что-то вроде этого будет работать в производной таблице, тогда вы можете присоединиться к ней, чтобы обновить все строки на основе набора

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

Это все еще может быть полезным подходом, если вы в конечном итоге устанавливаете идентификационную вставку, затем вставляете их все так, а затем удаляете их, ГДЕ 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
...