使用与csv中相同的列创建表

时间:2010-12-03 09:25:45

标签: sql sql-server-2005 tsql

我正在写一个stored procedure,它应该将csv文件和insert中的数据转换为table。我的问题是columns文件中csv的数量不固定(即columns的数量是可变的)。因此,我需要一些方法来创建temporary table,其columns文件的csv数与bulk insert完全相同。这样我就可以使用{{1}}。

3 个答案:

答案 0 :(得分:2)

改进了nadeems脚本......更加健壮一点。

此代码非常适合在不使用默认wizzards的情况下加载多个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 @stmt=@execsql 


   --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 @col=@col + '[' + 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 @stmt=@table

   --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 @stmt=@execsql 

end

GO

答案 1 :(得分:1)

您可以使用Powershell来处理CSV文件,您可以调整一个示例here,以考虑可变数量的字段。您可以构建SQL以创建表,然后发出批量加载。

答案 2 :(得分:1)

我尝试通过写一个sp来解决这个问题,它将csv文件路径作为参数,并创建一个表名为temptable,格式与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 @stmt=@execSQL 

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

       SET @col=@col + 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 @stmt=@table

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

   EXEC sp_executesql @stmt=@execSQL 

end