Pரத*_*ீப் 7 sql sql-server sql-server-2012 bulkupdate
我有一个Table Valued Constructor通过它选择周围的1 million记录.它将用于update另一个表.
SELECT *
FROM (VALUES (100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
.....
..... --1 million records
(100,200,300)) tc (proj_d, period_sid, val)
Run Code Online (Sandbox Code Playgroud)
这是我的原始查询:https://www.dropbox.com/s/ezomt80hsh36gws/TVC.txt?dl = 0#
当我执行上述操作时,select它只是显示查询已完成但出现错误并显示任何错误消息.
更新:尝试使用TRY/CATCH块捕获错误消息或错误号但不使用与先前映像相同的错误
BEGIN try
SELECT *
FROM (VALUES (100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
.....
..... --1 million records
(100,200,300)) tc (proj_d, period_sid, val)
END try
BEGIN catch
SELECT Error_number(),
Error_message()
END catch
Run Code Online (Sandbox Code Playgroud)
为什么它没有执行是否有表Valed构造函数的限制Select.我知道Insert它是1000,但我选择在这里.
尽管不建议对大量行使用此方法,但没有相关的硬编码限制(65,536 * 4KB 的网络数据包大小为 268 MB,而您的脚本长度远未达到此值)。
您看到的错误是由客户端工具而不是 SQL Server 引发的。如果你在动态SQL编译中构造SQL String至少是能够启动成功的
DECLARE @SQL NVARCHAR(MAX) = '(100,200,300),
';
SELECT @SQL = 'SELECT * FROM (VALUES ' + REPLICATE(@SQL, 1000000) + '
(100,200,300)) tc (proj_d, period_sid, val)';
SELECT @SQL AS [processing-instruction(x)]
FOR XML PATH('')
SELECT DATALENGTH(@SQL) / 1048576.0 AS [Length in MB] --30.517705917
EXEC(@SQL);
Run Code Online (Sandbox Code Playgroud)
虽然我在大约 30 分钟的编译时间后杀死了上面的内容,但它仍然没有产生一行。文字值需要作为常量表存储在计划本身内,并且 SQL Server 也花费大量时间尝试派生有关它们的属性。
SSMS 是一个 32 位应用程序,std::bad_alloc在解析批处理时会引发异常
它尝试将一个元素推送到已达到容量的 Token 向量上,但由于没有足够大的连续内存区域,其调整大小的尝试失败。所以该语句甚至从未到达服务器。
向量容量每次增长 50%(即按照此处的顺序)。向量需要增长到的容量取决于代码的布局方式。
以下需要将容量从 19 增加到 28。
SELECT * FROM
(VALUES
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300)) tc (proj_d, period_sid, val)
Run Code Online (Sandbox Code Playgroud)
而以下只需要尺寸为 2
SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val)
Run Code Online (Sandbox Code Playgroud)
以下需要容量 > 63 且 <= 94。
SELECT *
FROM (VALUES
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300)
) tc (proj_d, period_sid, val)
Run Code Online (Sandbox Code Playgroud)
对于如情况 1 那样布置的 100 万行,向量容量需要增长到 3,543,306。
您可能会发现以下任一操作都将使客户端解析成功。
然而,即使您成功地将其发送到服务器,无论如何,它最终只会在执行计划生成期间杀死服务器,如上所述。
使用导入导出向导来加载表会更好。如果您必须在 TSQL 中执行此操作,您会发现将其分成较小的批次和/或使用其他方法(例如分解 XML)将比表值构造函数执行得更好。例如,以下代码在我的计算机上执行需要 13 秒(尽管如果使用 SSMS,您仍然可能需要分成多个批次,而不是粘贴大量 XML 字符串文字)。
DECLARE @S NVARCHAR(MAX) = '<x proj_d="100" period_sid="200" val="300" />
' ;
DECLARE @Xml XML = REPLICATE(@S,1000000);
SELECT
x.value('@proj_d','int'),
x.value('@period_sid','int'),
x.value('@val','int')
FROM @Xml.nodes('/x') c(x)
Run Code Online (Sandbox Code Playgroud)