Sco*_*kay 2 t-sql sql-server cursor identity-insert
我试图为数据库中的一堆行设置一些id,其中id列是一个标识.
我创建了一个游标来遍历行并使用递增的负数(-1,-2,-3等)更新id.
当我只更新一行打开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
Run Code Online (Sandbox Code Playgroud)
有谁知道我做错了什么?
无论如何你都不需要光标.忽略它们是这样的标识列可以在派生表中工作然后你可以加入它以更新集合中的所有行
select 0-row_number() over( order by myRowId asc) as myRowId,*
 from dbo.myTable
WHERE myRowId > 17095
Run Code Online (Sandbox Code Playgroud)
这仍然可能是一个有用的方法,如果您最终设置标识插入然后插入所有像那样然后在事务中删除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
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1506 次  |  
        
|   最近记录:  |