sql-server - 光标内的IDENTITY_INSERT ON不允许插入ID

标签 sql-server tsql 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

有人知道我在做什么错吗?

最佳答案

无论如何,您将不需要光标。忽略它们是标识列,这样在派生表中将起作用,然后您可以加入表中以基于集合的方式更新所有行

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

关于sql-server - 光标内的IDENTITY_INSERT ON不允许插入ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2780571/

相关文章:

sql - 复制具有不同 ID 的记录

java - 选择哪里.... ms sql 2005 中需要电气状态

android - 我如何从 SQLITE 数据库获取数据到 android 中的数组?

sql-server - Excel 源 SSIS

sql - 使用动态 SQL 设置参数

sql - T SQL 条件字符串连接

java - SQLite 查询 - 一旦找到特定项目就停止从数据库返回行

java - Android 严格模式 java.lang.Throwable : Explicit termination method 'close' not called

sql-server - 将值数组插入 SQL Server 表的列中

mysql - Hibernate:将逆向工程模式从 SQL Server 传输到 MySQL