【发布时间】:2017-10-15 11:24:48
【问题描述】:
我在 SQL 中有一个表,其中包含 2 个字段 ID (int) 和 RawData (varchar(max))
原始数据字段包含管道分隔的数据
AB|1223445|01012017|abc|........
记录中有 75 个字段,最多有 100 万行。
我需要解析这些数据并将其放在另一个包含 75 个字段的表中。数据包含日期、整数、varchars(最大值为 varchar(70))、numeric(5,2) 和货币字段/数据类型。
目前我正在使用一个函数来拆分字符串,然后旋转返回的数据并将其插入表中。但这需要 4 个小时。
有更快的方法吗?
我正在使用 SQL 2014
如果我没有提供足够的信息,请向我提出任何问题。
谢谢
仅供参考
用于分割每条记录的函数
ALTER FUNCTION [dbo].[fn_SplitString]
(
@string NVARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @output TABLE(ID int, splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE @start INT, @end INT, @Count INT
set @Count = 1
SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
WHILE @start < LEN(@string) + 1 BEGIN
IF @end = 0
SET @end = LEN(@string) + 1
INSERT INTO @output (ID, splitdata)
VALUES(@Count, SUBSTRING(@string, @start, @end - @start))
SET @start = @end + 1
SET @end = CHARINDEX(@delimiter, @string, @start)
Set @Count = @Count+1
END
RETURN
END
每条记录都使用 PIVOT
While @CountRec > 0
BEGIN
Select top(1) @RawData = RawData from @RawDataTable
Insert into RawData_Parsed(01, 02, 03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
61,62,63,64,65,66,67,68,69,70,71,72,73,74,75)
select [1],[2],[3],substring([4],5,4) +'/'+ substring([4],3,2) +'/'+ substring([4],1,2),[5],[6],[7],[8],[9],[10],[11],[12],[13],
case when len([14]) = 0 then NULL else substring([14],5,4) +'/'+ substring([14],3,2) +'/'+ substring([14],1,2) end,
case when len([15]) = 0 then NULL else substring([15],5,4) +'/'+ substring([15],3,2) +'/'+ substring([15],1,2) end,
case when len([16]) = 0 then NULL else substring([16],5,4) +'/'+ substring([16],3,2) +'/'+ substring([16],1,2) end,
case when len([17]) = 0 then NULL else substring([17],5,4) +'/'+ substring([17],3,2) +'/'+ substring([17],1,2) end,
case when len([18]) = 0 then NULL else substring([18],5,4) +'/'+ substring([18],3,2) +'/'+ substring([18],1,2) end,
[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31],
case when len([32]) = 0 then NULL else substring([32],5,4) +'/'+ substring([32],3,2) +'/'+ substring([32],1,2) end,
case when len([33]) = 0 then NULL else substring([33],5,4) +'/'+ substring([33],3,2) +'/'+ substring([33],1,2) end,
[34],[35],[36],[37],[38],[39],[40],[41],
case when len([42]) = 0 then NULL else substring([42],5,4) +'/'+ substring([42],3,2) +'/'+ substring([42],1,2) end,
case when len([43]) = 0 then NULL else substring([43],5,4) +'/'+ substring([43],3,2) +'/'+ substring([43],1,2) end,
[44],
case when len([45]) = 0 then NULL else [45] end,
[46],[47],
case when len([48]) = 0 then NULL else substring([48],5,4) +'/'+ substring([48],3,2) +'/'+ substring([48],1,2) end,
case when len([49]) = 0 then NULL else substring([49],5,4) +'/'+ substring([49],3,2) +'/'+ substring([49],1,2) end,
[50],
case when len([51]) = 0 then NULL else [51] end,
[52],[53],
case when len([54]) = 0 then NULL else substring([54],5,4) +'/'+ substring([54],3,2) +'/'+ substring([54],1,2) end,
case when len([55]) = 0 then NULL else substring([55],5,4) +'/'+ substring([55],3,2) +'/'+ substring([55],1,2) end,
[56],
case when len([57]) = 0 then NULL else [57] end,
[58],[59],
case when len([60]) = 0 then NULL else substring([60],5,4) +'/'+ substring([60],3,2) +'/'+ substring([60],1,2) end,
case when len([61]) = 0 then NULL else substring([61],5,4) +'/'+ substring([61],3,2) +'/'+ substring([61],1,2) end,
[62],
case when len([63]) = 0 then NULL else [63] end,
[64],[65],
case when len([66]) = 0 then NULL else substring([66],5,4) +'/'+ substring([66],3,2) +'/'+ substring([66],1,2) end,
case when len([67]) = 0 then NULL else substring([67],5,4) +'/'+ substring([67],3,2) +'/'+ substring([67],1,2) end,
[68],
case when len([69]) = 0 then NULL else [69] end,
[70],[71],
case when len([72]) = 0 then NULL else substring([72],5,4) +'/'+ substring([72],3,2) +'/'+ substring([72],1,2) end,
case when len([73]) = 0 then NULL else substring([73],5,4) +'/'+ substring([73],3,2) +'/'+ substring([73],1,2) end,
[74],
case when len([75]) = 0 then NULL else [75] end,
@JobTaskID
from
(
select ID,splitData from dbo.fn_splitstring(@RawData, '|')
) src
pivot
(
MAX(splitData) for Id in ( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25]
,[26],[27],[28],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[48]
,[49],[50],[51],[52],[53],[54],[55],[56],[57],[58],[59],[60],[61],[62],[63],[64],[65],[66],[67],[68],[69],[70],[71]
,[72],[73],[74],[75])
) piv;
delete top(1) from @RawDataTable
set @CountRec = @CountRec - 1
set @RawData = null
end
【问题讨论】:
-
忘掉次优的分割函数。将 src 表导出到文件并使用 BULK 导入到目标表。
-
@lad2025 没想到,谢谢
-
添加一些示例数据和期望的结果,这可能有助于解决您的问题。
-
@YogeshSharma 期望的结果是快速将数据拆分并转换为正确的格式。将字段拆分为 varchars 只会稍微快一点,所以我认为数据几乎无关紧要。问题是我用来分割数据的方法
标签: sql sql-server