F.e.你D:\
驱动器上得到了CSV文件名sample.csv
,这个里面:
Heading1,Heading2,Heading3
1,Monday,2.45
2,Monday,3.765
然后你可以使用此查询:
DECLARE @str nvarchar(max),
@x xml,
@head xml,
@sql nvarchar(max),
@params nvarchar(max) = '@x xml'
SELECT @str = BulkColumn
FROM OPENROWSET (BULK N'D:\sample.csv', SINGLE_CLOB) AS a
SELECT @head = CAST('<row><s>'+REPLACE(SUBSTRING(@str,1,CHARINDEX(CHAR(13)+CHAR(10),@str)-1),',','</s><s>')+'</s></row>' as xml)
SELECT @x = CAST('<row><s>'+REPLACE(REPLACE(SUBSTRING(@str,CHARINDEX(CHAR(10),@str)+1,LEN(@str)),CHAR(13)+CHAR(10),'</s></row><row><s>'),',','</s><s>')+'</s></row>' as xml)
SELECT @sql = N'
SELECT t.c.value(''s[1]'',''int'') '+QUOTENAME(t.c.value('s[1]','nvarchar(max)'))+',
t.c.value(''s[2]'',''nvarchar(max)'') '+QUOTENAME(t.c.value('s[2]','nvarchar(max)'))+',
t.c.value(''s[3]'',''decimal(15,7)'') '+QUOTENAME(t.c.value('s[3]','nvarchar(max)'))+'
FROM @x.nodes(''/row'') as t(c)'
FROM @head.nodes('/row') as t(c)
为了得到这样的输出:
Heading1 Heading2 Heading3
1 Monday 2.4500000
2 Monday 3.7650000
起初我们在OPEROWSET的帮助下将数据作为SINGLE_CLOB
。
然后,我们把所有在@str
变量。从开头到第一个部分\r\n
我们把@head
,另一部分在@x
转换成XML。结构:
<row>
<s>Heading1</s>
<s>Heading2</s>
<s>Heading3</s>
</row>
<row>
<s>1</s>
<s>Monday</s>
<s>2.45</s>
</row>
<row>
<s>2</s>
<s>Monday</s>
<s>3.765</s>
</row>
之后,我们建立一个像动态查询:
SELECT t.c.value('s[1]','int') [Heading1],
t.c.value('s[2]','nvarchar(max)') [Heading2],
t.c.value('s[3]','decimal(15,7)') [Heading3]
FROM @x.nodes('/row') as t(c)
并执行它。变量@x
作为参数传递。
希望这可以帮助你。
CSV文件有多大?如果需要,你可以假设使用Excel。请注意,'BULK INSERT'不提供真正的CSV解析器:它不支持转义引号,甚至不支持引号值中的逗号(http://stackoverflow.com/questions/12902110/bulk-insert-correctly-quoted-csv-文件在SQL服务器)例如。 – Dai
最大的CSV文件大小约为2MB。数据不包含任何逗号或转义引号。 – fila
基本上有三个选项 - 首先看看BULK INSERT是否适合您的文件,如建议。如果不是,您可能需要使用SSIS,或者您可以使用外部进程(如PowerShell脚本)来推送数据。 –