2010-12-03 2 views
1

Ich schreibe eine stored procedure Erstellen Tabelle, die Daten aus einer Datei csv und insert in eine table nehmen soll. Mein Problem ist, dass die Nummer columns in der Datei csv nicht fest ist (dh die Nummer columns ist variabel). Also brauche ich einen Weg, um eine temporarytable mit genau der gleichen Anzahl von columns wie in der csv Datei zu erstellen. Damit kann ich bulk insert verwenden.mit den gleichen Spalten wie in einer csv

Antwort

1

Nun habe ich versucht, das Problem zu lösen, indem ich eine sp schreibe, die den csv-Dateipfad als Parameter verwendet und einen Tabellennamen mit demselben Format wie die Anzahl der Spalten in der CSV-Datei erstellt. CSV-Datei sieht aus wie

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

Stored Proc Skript

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

Sie könnten Powershell verwenden, um die CSV-Datei zu verarbeiten, es gibt ein Beispiel here, das Sie wahrscheinlich anpassen könnten, um die variable Anzahl der Felder zu berücksichtigen. Sie können das SQL erstellen, um eine Tabelle zu erstellen, und dann eine Massenlast ausgeben.

+0

+1 für die Erzählung etwas Neues. –

2

verbesserte nadeems Skript ... Ein wenig robuster.

Dieser Code eignet sich hervorragend zum Laden mehrerer CSV-Dateien ohne Verwendung der Standard-Wizzards.

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 
Verwandte Themen