【发布时间】:2016-03-21 13:02:39
【问题描述】:
我正在将一个 csv 文件批量插入 SQL Server 2012。数据当前是 | 管道分隔为每一行的一个长字符串。我想将数据分成每个管道的不同列。
这是导入数据后的样子:
ID|ID2|Person|Person2|City|State
"1"|"ABC"|"Joe"|"Ben"|"Boston"|"MA"
"2"|"ABD"|"Jack"|"Tim"|"Nashua"|"NH"
"3"|"ADC"|"John"|"Mark"|"Hartford"|"CT"
我想将数据分成每个管道的列:
ID ID2 Person Person2 City State
1 ABC Joe Ben Boston MA
2 ABD Jack Tim Nashua NH
3 AFC John Mark Hartford CT
我发现使用 charindex and substring functions 很困难,因为数据的列数我也尝试使用 ParseName,因为这是 2012 年的函数,但由于所有列都出来了,所以这也不起作用ParseName 为 NULL
该文件包含大约 300k 行,我找到了使用 xmlname 的解决方案,但速度很慢。即:需要一分钟来分离数据。
这里是慢 xml 解决方案:
CREATE TABLE #tbl(iddata varchar(200))
DECLARE @i int = 0
WHILE @i < 100000
BEGIN
SET @i = @i + 1
INSERT INTO #tbl(iddata)
SELECT '"1"|"ABC"|"Joe"|"Ben"|"Boston"|"MA"'
UNION ALL
SELECT '"2"|"ABD"|"Jack"|"Tim"|"Nashua"|"NH"'
UNION ALL
SELECT '"3"|"AFC"|"John"|"Mark"|"Hartford"|"CT"'
END
;WITH XMLData
AS
(
SELECT idData,
CONVERT(XML,'<IDs><id>'
+ REPLACE(iddata,'|', '</id><id>') + '</id></IDs>') AS xmlname
FROM (
SELECT REPLACE(iddata,'"','') as iddata
FROM #tbl
)x
)
SELECT xmlname.value('/IDs[1]/id[1]','varchar(100)') AS ID,
xmlname.value('/IDs[1]/id[2]','varchar(100)') AS ID2,
xmlname.value('/IDs[1]/id[3]','varchar(100)') AS Person,
xmlname.value('/IDs[1]/id[4]','varchar(100)') AS Person2,
xmlname.value('/IDs[1]/id[5]','varchar(100)') AS City,
xmlname.value('/IDs[1]/id[6]','varchar(100)') AS State
FROM XMLData
【问题讨论】:
-
这个问题包含了一个好问题所需要的一切:复制'n'可粘贴的测试数据、输入、预期输出、自己的尝试和一个明确的问题。从我这边投票
标签: sql-server tsql sql-server-2012 csv