Sql server 向具有rowversion/timestamp列的表插入大量行时出错(SQL Server 2016)
我试图使用insert INTO/SELECT语句将大量行插入到具有rowversion/timestamp列的表中 INSERT语句始终返回错误: 为数据库生成新DBT时发生内部错误。 请重试该操作 将单个事务中的数据插入具有rowversion/timestamp列的表时,是否有大小限制 我已经阅读了所有与MSDN相关的页面,似乎这应该是可行的。它看起来很奇怪,像一只虫子。我使用以下SQL Server版本(全部为Enterprise x64)在3台不同的服务器(全部为VMware虚拟化)上尝试了相同的方法:Sql server 向具有rowversion/timestamp列的表插入大量行时出错(SQL Server 2016),sql-server,sql-server-2016,Sql Server,Sql Server 2016,我试图使用insert INTO/SELECT语句将大量行插入到具有rowversion/timestamp列的表中 INSERT语句始终返回错误: 为数据库生成新DBT时发生内部错误。 请重试该操作 将单个事务中的数据插入具有rowversion/timestamp列的表时,是否有大小限制 我已经阅读了所有与MSDN相关的页面,似乎这应该是可行的。它看起来很奇怪,像一只虫子。我使用以下SQL Server版本(全部为Enterprise x64)在3台不同的服务器(全部为VMware虚拟化)上
- 13.0.4411.0
- 13.0.4001.0
- 13.0.2164.0
USE Db1
GO
DROP TABLE IF EXISTS [dbo].[TESTTABLE]
GO
-- insert 400 million dummy records
SELECT
TOP 400000000 IDENTITY(int,1,1) AS Number
INTO
[dbo].[TESTTABLE]
FROM
sys.columns s1
CROSS JOIN
sys.columns s2
CROSS JOIN
sys.columns s3
USE Db2
GO
DROP TABLE IF EXISTS [dbo].[TESTTABLE]
GO
-- create table with a timestamp/rowversion column
CREATE TABLE [dbo].[TESTTABLE](
[StageTimestamp] [timestamp] NOT NULL,
[SomeNumber] [int] NOT NULL
)
GO
-- insert 400 million records into the table
INSERT INTO
[dbo].[TESTTABLE] WITH (TABLOCK) (SomeNumber)
SELECT
Number
FROM
[db1].[dbo].[TESTTABLE]
GO
这不是一个永久的固定,但做了一些尝试和错误,并拿出了一个解决办法。当插入较小的记录块时,插入工作正常,经过1000万和5000万块的测试,插入不会失败。脚本的第二部分已更新为循环
USE Db2
GO
DROP TABLE IF EXISTS [dbo].[TESTTABLE]
GO
-- create table with a timestamp/rowversion column
CREATE TABLE [dbo].[TESTTABLE](
[StageTimestamp] [timestamp] NOT NULL,
[SomeNumber] [int] NOT NULL
)
GO
DECLARE @rowcount INT = 1
DECLARE @LastNumber INT = 0
WHILE (@rowcount > 0)
BEGIN
--insert 50 million blocks of records into the table
INSERT INTO
[dbo].[TESTTABLE] WITH (TABLOCK) (SomeNumber)
SELECT TOP(50000000)
Number
FROM
[db1].[dbo].[TESTTABLE]
WHERE Number > @LastNumber
--get insert rows, it will loop until no more rows is inserted
SET @rowcount = @@ROWCOUNT
--get the last number
SELECT @LastNumber = MAX(SomeNumber) FROM [dbo].[TESTTABLE]
END
GO
这不是一个永久的固定,但做了一些尝试和错误,并拿出了一个解决办法。当插入较小的记录块时,插入工作正常,经过1000万和5000万块的测试,插入不会失败。脚本的第二部分已更新为循环
USE Db2
GO
DROP TABLE IF EXISTS [dbo].[TESTTABLE]
GO
-- create table with a timestamp/rowversion column
CREATE TABLE [dbo].[TESTTABLE](
[StageTimestamp] [timestamp] NOT NULL,
[SomeNumber] [int] NOT NULL
)
GO
DECLARE @rowcount INT = 1
DECLARE @LastNumber INT = 0
WHILE (@rowcount > 0)
BEGIN
--insert 50 million blocks of records into the table
INSERT INTO
[dbo].[TESTTABLE] WITH (TABLOCK) (SomeNumber)
SELECT TOP(50000000)
Number
FROM
[db1].[dbo].[TESTTABLE]
WHERE Number > @LastNumber
--get insert rows, it will loop until no more rows is inserted
SET @rowcount = @@ROWCOUNT
--get the last number
SELECT @LastNumber = MAX(SomeNumber) FROM [dbo].[TESTTABLE]
END
GO
我来这里是因为这是用德语查找错误时的第一个结果。我做了更多的挖掘,在这里找到了这篇博文: 它很好地解释了背景中发生的事情,以便更好地理解这个问题 我通过捕获错误,将任务设置为睡眠。5秒,然后再次发送相同的命令,解决了我的问题
我设置了10次重试的限制,但到目前为止还没有达到。我来到这里是因为这是用德语查找错误时的第一个结果。我做了更多的挖掘,在这里找到了这篇博文: 它很好地解释了背景中发生的事情,以便更好地理解这个问题 我通过捕获错误,将任务设置为睡眠。5秒,然后再次发送相同的命令,解决了我的问题
我设置了10次重试的限制,但到目前为止还没有达到。在db1 testtable conatins 1列中,db2 testtable包含两个字段。也许您需要在insert中指定字段列表?列列表在insert(“SomeNumber”列)中指定。另一列“StageTimestamp”应该自动填充(这就是它的要点)——这就是为什么列列表中没有指定它的原因。看起来2016年DBTS可能有问题。在microsoft connect上发现:似乎如此。我刚刚在SQL Server 2014上测试了它,它作为一个单独的实例安装在同一台服务器上,并在SQL 2014上运行。这很奇怪,但实际上似乎是SQL 2016数据库引擎中的一个bug。@saso我希望您将此提交给microsoft connect。db2testtable包含两个字段。也许您需要在insert中指定字段列表?列列表在insert(“SomeNumber”列)中指定。另一列“StageTimestamp”应该自动填充(这就是它的要点)——这就是为什么列列表中没有指定它的原因。看起来2016年DBTS可能有问题。在microsoft connect上发现:似乎如此。我刚刚在SQL Server 2014上测试了它,它作为一个单独的实例安装在同一台服务器上,并在SQL 2014上运行。这很奇怪,但实际上似乎是SQL 2016数据库引擎中的一个bug。@saso我希望您将此提交给microsoft connect。