F.e. you got CSV file names sample.csv
on D:\
drive, with this inside:
Heading1,Heading2,Heading3
1,Monday,2.45
2,Monday,3.765
Then you can use this query:
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)
To get output like:
Heading1 Heading2 Heading3
1 Monday 2.4500000
2 Monday 3.7650000
At first we take data as SINGLE_CLOB
with the help of OPEROWSET.
Then we put all in @str
variable. The part from beginning to first \r\n
we put in @head
, the other part in @x
with conversion to XML. Structure:
<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>
After that we build dynamic query like:
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)
And execute it. Variable @x
is passing as parameter.
Hope this helps you.