目前我们导入一个表Import_File,它有一个Options列,该列具有分隔值。 我们需要将这些分隔值加载到不同的表中。
目前我们一次只做一行,因为行数可以是100k +
有没有办法加快下面的代码?
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
答案 0 :(得分:2)
我见过光标的唯一原因&amp;用于此类事情的TRY / CATCH块用于在开发新的ETL过程时识别和分析不良记录。如果那不是你正在做的事情那么光标不是必需的,会让你慢下来。
让我们回顾一下你在做什么:
你应该做什么
请注意我是如何使用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);
<强>结果
item
-----
abc
cde
fff
选项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;
选项2
获取DelimitedSplit8K的副本并使用它来进行拆分。
WITH split AS
(
Select
import.InventoryId,
import.OPTIONS
From Import_File import with (nolock)
CROSS APPLY dbo.DelimitedSplit8K(import.OPTIONS, ',')
Where
import.options IS NOT NULL
And ISNULL(import.IsFeatureProcessed,0) = 0
And LEN(ISNULL(import.OPTIONS,''))>10
And import.InventoryId Is Not Null
)
Insert Into Import_File_Feature
(
FeatureId,
InventoryId,
FeatureText,
FeatureGroup,
FeatureCategory,
FeatureIsAvailable,
FeatureIsStandard
)
Select
newid(),
import.InventoryId,
item,
'',
'',
1,
1
FROM split
请注意,因为我没有任何表定义或示例数据,所以我无法测试上面的代码。