Sql server 将MSSQL批量字符串插入到XML中
目前,我们导入一个表import_文件,该文件有一个带有分隔值的选项列。 我们需要将这些分隔值加载到另一个表中 目前,我们一次只做一行,因为行数可能是100k,所以速度会慢一些+ 有没有办法加速下面的代码Sql server 将MSSQL批量字符串插入到XML中,sql-server,xml,tsql,Sql Server,Xml,Tsql,目前,我们导入一个表import_文件,该文件有一个带有分隔值的选项列。 我们需要将这些分隔值加载到另一个表中 目前,我们一次只做一行,因为行数可能是100k,所以速度会慢一些+ 有没有办法加速下面的代码 Declare @InvId uniqueidentifier Declare @xml xml Declare CurrFeatureList Cursor For Select import.InventoryId, N'<root><r><
Declare @InvId uniqueidentifier
Declare @xml xml
Declare CurrFeatureList Cursor For
Select
import.InventoryId,
N'<root><r><![CDATA[' + replace( import.OPTIONS ,',',']]></r><r><![CDATA[') + ']]></r></root>'
From Import_File import with (nolock)
Where
import.options IS NOT NULL
And ISNULL(import.IsFeatureProcessed,0) = 0
And LEN(ISNULL(import.OPTIONS,''))>10
And import.InventoryId Is Not Null
OPEN CurrFeatureList
FETCH NEXT FROM CurrFeatureList
INTO @InvId, @xml
Print 'Inventory Import #10000'
Print GetDate()
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
Insert Into Import_File_Feature
(
FeatureId,
InventoryId,
FeatureText,
FeatureGroup,
FeatureCategory,
FeatureIsAvailable,
FeatureIsStandard
)
Select
NEWID(),
@InvId,
t.value('.','varchar(250)'),
'',
'',
1,
1
From @xml.nodes('//root/r') as a(t)
FETCH NEXT FROM CurrFeatureList
INTO @InvId, @xml
END TRY
BEGIN CATCH
Print 'Error '
Print @InvId
Print ERROR_NUMBER()
Print ERROR_SEVERITY()
Print ERROR_STATE()
Print ERROR_PROCEDURE()
Print ERROR_LINE()
Print ERROR_MESSAGE()
FETCH NEXT FROM CurrFeatureList
INTO @InvId, @xml
END CATCH
END
Close CurrFeatureList
Deallocate CurrFeatureList
GO
我见过用于这种事情的cursor&TRY/CATCH块的唯一原因是,在开发新的ETL过程时,用于识别和分析不良记录。如果这不是你正在做的,那么光标是不需要的,它会减慢你的速度 让我们回顾一下您正在做的工作: 您正在将数据拉入游标CurrFeatureList,并将Import_File.Options转换为XML字段,以便以后可以使用XML节点方法拆分字符串。 启动光标 对于每个InventoryId,您需要: A.将Import_File.Options拆分为多行 B将该InventoryId和关联行插入导入文件功能 C如果出现错误,请打印它并转到下一条记录 你应该做什么 请注意我是如何使用XML节点拆分此字符串的:
DECLARE @x varchar(100) = 'abc,cde,fff';
SELECT item = xxx.value('(text())[1]', 'varchar(100)')
FROM (VALUES (CAST(('<r>'+REPLACE(@x,',','</r><r>') +'</r>') AS xml))) x(xx)
CROSS APPLY xx.nodes('r') xxx(xxx);
选择1
将初始联接和后续XML/XML节点拆分器逻辑组合到一条语句中,然后执行插入操作:
WITH
yourData AS
(
Select
import.InventoryId,
x = N'<r><![CDATA[' + replace( import.OPTIONS ,',',']]></r><r><![CDATA[') + ']]></r>'
From Import_File import with (nolock)
Where
import.options IS NOT NULL
And ISNULL(import.IsFeatureProcessed,0) = 0
And LEN(ISNULL(import.OPTIONS,''))>10
And import.InventoryId Is Not Null
),
split AS
(
SELECT InventoryId, item = i.value('.', 'varchar(8000)')
FROM yourData
CROSS APPLY x.nodes('r') s(i)
)
Insert Into Import_File_Feature
(
FeatureId,
InventoryId,
FeatureText,
FeatureGroup,
FeatureCategory,
FeatureIsAvailable,
FeatureIsStandard
)
Select
newid(),
import.InventoryId,
item, -- this is the split out item from import.Options
'',
'',
1,
1
FROM split;
请注意,因为我没有任何表定义或示例数据,所以我无法测试上面的代码。我见过用于此类操作的cursor&TRY/CATCH块的唯一原因是,在开发新的ETL过程时,用于识别和分析坏记录。如果这不是你正在做的,那么光标是不需要的,它会减慢你的速度 让我们回顾一下您正在做的工作: 您正在将数据拉入游标CurrFeatureList,并将Import_File.Options转换为XML字段,以便以后可以使用XML节点方法拆分字符串。 启动光标 对于每个InventoryId,您需要: A.将Import_File.Options拆分为多行 B将该InventoryId和关联行插入导入文件功能 C如果出现错误,请打印它并转到下一条记录 你应该做什么 请注意我是如何使用XML节点拆分此字符串的:
DECLARE @x varchar(100) = 'abc,cde,fff';
SELECT item = xxx.value('(text())[1]', 'varchar(100)')
FROM (VALUES (CAST(('<r>'+REPLACE(@x,',','</r><r>') +'</r>') AS xml))) x(xx)
CROSS APPLY xx.nodes('r') xxx(xxx);
选择1
将初始联接和后续XML/XML节点拆分器逻辑组合到一条语句中,然后执行插入操作:
WITH
yourData AS
(
Select
import.InventoryId,
x = N'<r><![CDATA[' + replace( import.OPTIONS ,',',']]></r><r><![CDATA[') + ']]></r>'
From Import_File import with (nolock)
Where
import.options IS NOT NULL
And ISNULL(import.IsFeatureProcessed,0) = 0
And LEN(ISNULL(import.OPTIONS,''))>10
And import.InventoryId Is Not Null
),
split AS
(
SELECT InventoryId, item = i.value('.', 'varchar(8000)')
FROM yourData
CROSS APPLY x.nodes('r') s(i)
)
Insert Into Import_File_Feature
(
FeatureId,
InventoryId,
FeatureText,
FeatureGroup,
FeatureCategory,
FeatureIsAvailable,
FeatureIsStandard
)
Select
newid(),
import.InventoryId,
item, -- this is the split out item from import.Options
'',
'',
1,
1
FROM split;
请注意,由于我没有任何表定义或示例数据,因此我无法测试上述代码。似乎光标可以替换为INSERT INTO SELECT…Agree with@Rigerta。您在游标中没有做任何真正需要游标的事情。是的,但我不知道如何在单个语句中执行select/JOIN。理论上是的,这听起来是正确的方法,但我没有太多地使用XML,所以不确定如何构建SQL。关于从哪里开始的任何建议?似乎光标可以替换为插入选择…同意@Rigerta。您在游标中没有做任何真正需要游标的事情。是的,但我不知道如何在单个语句中执行select/JOIN。理论上是的,这听起来是正确的方法,但我没有太多地使用XML,所以不确定如何构建SQL。关于从哪里开始有什么建议吗?为了让选项2发挥作用,我不得不做两个小小的改变。1我必须将import.OPTIONS强制转换为XML当前它们是varchar 2删除import.InventoryId并将其保留为InventoryId。谢谢你的帮助,这为我节省了大量的处理时间并加快了速度。我不能百分之百确定的一种情况是,当varchar具有&or