2010-12-03 21 views
1

我正在編寫一個stored procedure,它應該將數據從csv文件和insert轉換爲table。我的問題是csv文件中的columns的數量不固定(即columns的數量是可變的)。所以我需要一些方法來創建一個temporarytable,其編號與csv文件中的完全相同,編號爲columns。這樣我可以使用bulk insert使用與csv相同的列創建表

回答

1

嗯,我試着通過編寫一個將csv文件路徑作爲參數的sp來解決這個問題,並使用與csv中的列數相同的格式創建表名作爲臨時表。 CSV文件看起來像

eid,ename,esalary,etemp 
1,Mark,1000, 
2,Peter,1000, 

存儲過程腳本

create proc createtable 
@path nvarchar(50) 
as 
begin 
declare @execSQL nvarchar(1000) 
declare @tempstr varchar(1000) 
declare @col varchar(1000) 
declare @table nvarchar(1000) 

-- Create a temp table to with one column to hold the first row of the csv file 

    CREATE TABLE #tbl (line VARCHAR(1000)) 
    SET @execSQL = 
     'BULK INSERT #tbl 
     FROM ''' + @path + ''' 
     WITH ( 
       FIELDTERMINATOR =''\n'', 
       FIRSTROW = 1, 
       ROWTERMINATOR = ''\n'', 
       LASTROW = 1 
      )   
     ' 

    EXEC sp_executesql @[email protected] 

    SET @col = '' 
    SET @tempstr = (SELECT TOP 1 RTRIM(REPLACE(Line, CHAR(9), ',')) FROM #tbl) 
    DROP TABLE #tbl 
    WHILE CHARINDEX(',',@tempstr) > 0 
    BEGIN   

     SET @[email protected] + LTRIM(RTRIM(SUBSTRING(@tempstr, 1, CHARINDEX(',',@tempstr)-1))) + ' varchar(100),'  

     SET @tempstr = SUBSTRING(@tempstr, CHARINDEX(',',@tempstr)+1, len(@tempstr)) 
    END 
    SET @col = @col + @tempstr + ' varchar(100)' 

    if object_id('temptable') is not null 
    drop table temptable 

    SET @table = 'create table temptable (' + @col + ')' 

    EXEC sp_executesql @[email protected] 

-- Load data from csv 
    SET @execSQL = 
     'BULK INSERT temptable 
     FROM ''' + @path + ''' 
     WITH ( 
       FIELDTERMINATOR ='','', 
       FIRSTROW = 2, 
       ROWTERMINATOR = ''\n''    
      )   
     ' 

    EXEC sp_executesql @[email protected] 

end 
1

您可以使用Powershell來處理CSV文件,有一個示例here,您可能會考慮到可變數量的字段。您可以構建SQL來創建表,然後發出批量加載。

+0

+1告訴我新的東西。 – 2010-12-04 10:20:03

2

改進nadeems腳本...有一點更加穩健。

此代碼非常適合加載多個CSV文件而不使用默認的風險。

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 


CREATE proc [dbo].[importeer_csv_as_table] 
@path nvarchar(255), 
@new_table_name varchar(255), 
@field_terminator varchar(255), 
@row_terminator varchar(255) 
as 
begin 
declare @execsql nvarchar(max) 
declare @tempstr varchar(max) 
declare @col varchar(max) 
declare @table nvarchar(max) 
declare @drop_table varchar(max) 


-- Create a temp table to with one column to hold the first row of the csv file 

    create table #tbl (line varchar(1000)) 
    set @execsql = 
     'bulk insert #tbl 
     from ''' + @path + ''' 
     with ( 
       fieldterminator =''' + @row_terminator + ''', 
       firstrow = 1, 
       rowterminator = ''' + @row_terminator + ''', 
       lastrow = 1 
      )   
     ' 

    exec sp_executesql @[email protected] 


    --replace field terminator with comma 
    update #tbl set line = replace(line, @field_terminator, ',') 

    set @col = '' 
    set @tempstr = (select top 1 rtrim(replace(line, char(9), ',')) from #tbl) 
    drop table #tbl 
    while charindex(',',@tempstr) > 0 
    begin   

     set @[email protected] + '[' + ltrim(rtrim(substring(@tempstr, 1, charindex(',',@tempstr)-1))) + '] varchar(max),'  

     set @tempstr = substring(@tempstr, charindex(',',@tempstr)+1, len(@tempstr)) 
    end 
    set @col = @col + '[' + @tempstr + '] varchar(max)' 

    if object_id(@new_table_name) is not null 
    begin 
     set @drop_table = 'drop table [' + @new_table_name + ']' 

     exec sp_executesql @stmt= @drop_table 
    end 

    set @table = 'create table [' + @new_table_name + '] (' + @col + ')' 

    --select @table 


    exec sp_executesql @[email protected] 

    --Load data from csvle 
    set @execsql = 
     'bulk insert [' + @new_table_name + '] 
     from ''' + @path + ''' 
     with ( 
       fieldterminator =''' + @field_terminator + ''', 
       firstrow = 2, 
       rowterminator = ''' + @row_terminator + '''    
      )   
     ' 

    exec sp_executesql @[email protected] 

end 

GO 
相關問題