【问题标题】:SQL Server Bulk import data from .csv into new tableSQL Server 将 .csv 中的数据批量导入新表
【发布时间】:2016-03-03 19:37:38
【问题描述】:

我似乎找不到这个非常琐碎问题的答案。

我想将数据从.csv 文件(列数未知,以逗号分隔)文件批量导入现有数据库中的新 SQL Server 表。如果表是预定义的,BULK INSERT 语句可以正常工作,但由于我不知道.csv 文件的列数,所以这不起作用。

我尝试将 bulk 与 openrowset 结合使用,但无法正常工作。

顺便说一句:在这种情况下,SSIS 不是一个选项,因为我想将查询合并到 R (sqlquery) 或 Python 中。

我们将不胜感激!

【问题讨论】:

  • 只是为了清楚。您希望接收各种宽度和长度的文件 (.csv),并希望以编程方式将它们导入到一个新表中,每个文件一个,导入到您的 MS-SQL 数据库中。这是对您问题的正确解释吗?
  • 是的。理想情况下,我编写了一个查询,我总是可以使用它来将 .csv 导入到新表中。 .csv 文件的第一行包含列名。
  • 这似乎是一场等待发生的意外。使用 SQL Server 导入和导出向导(基于每个文件)有什么问题?
  • 我必须每天为多个 .csv 文件执行此操作,并且想要安排它。 .csv 文件命名方便,可用作新表的名称。我理解您的评论,但认为在这种情况下,以编程方式导入数据会对我有很大帮助。
  • 在文件格式不固定时导入数据异常困难。如果我必须这样做——相信我,我只会在对决定使用流动数据格式的人发誓之后才会这样做——我会使用 PowerShell 或 Python 之类的东西来读取和解析文件,使用启发式确定文件格式,然后在插入数据之前创建目标表。我的目标格式很可能是一个表,所有字段都为 VARCHAR 字段,并且可能根本没有主键。

标签: sql sql-server csv bulkinsert


【解决方案1】:

我找到了一种解决方法,使用 R 来解决上述问题。相同的逻辑可以应用于其他语言。建议大家使用这个功能的时候记住上面有用的cmets。

我写了一个小函数来捕捉 R 中的步骤:

SQLSave <- function(dbhandle, data, tablename) { 
  # Export data to temp path, for example within your SQL Server directory.
  write.csv2(data,file = "\\\\pathToSQL\\temp.csv",row.names=FALSE,na="")

  # Write first 100 rows to SQL Server, to incorporate the data structure.
  sqlSave(dbhandle, head(data,100), tablename = tablename, rownames = FALSE, safer = FALSE)

  # SQL Query to remove data in the table, structure remains:
  sqlQuery(dbhandle,paste("DELETE FROM [",tablename,"]",sep=""));

  # SQL Query to bulk insert all data from temp .csv to SQL Server
  sqlQuery(dbhandle,paste("BULK INSERT [",tablename,"]
           FROM '\\\\pathToSQL\\temp.csv'
           WITH
           (
             FIELDTERMINATOR = ';',
             ROWTERMINATOR = '\\n',
             FIRSTROW = 2,
             KEEPNULLS
           )",sep=""));

  # Delete temp file from file directory
  file.remove("\\\\pathToSQL\\temp.csv")
}

【讨论】:

    【解决方案2】:

    我目前正在努力解决同样的问题。我首先使用批量插入读取了第一行(标题)并创建了表。然后再次使用表中第 2 行导入数据的批量插入。虽然您必须在检查导入的数据后更改数据类型。

    CREATE TABLE #Header(HeadString nvarchar(max))
    
    declare @TableName nvarchar(100)='byom.DenormReportingData_100_100'
    DECLARE @Columns nvarchar(max)=''
    declare @Query nvarchar(max)=''
    DECLARE @QUERY2 NVARCHAR(MAX)=''
    bulk insert #Header
    from 'F:/Data/BDL_BI_Test.csv'
    with(firstrow=1,lastrow=1)
    
    select @Columns=(select quotename(value)+' VARCHAR(500)'+',' from #Header cross apply string_split(HeadString,',') for xml path(''))
    if isnull(@Columns,'')<>''
    begin
    set @Columns = left(@Columns,len(@Columns)-1)
    
    select @Query=@Query+'CREATE TABLE '+@TableName+' ('+@Columns+')'
    exec(@QUERY)
    end
    
    select @QUERY2 =@QUERY2+'bulk insert '+@TableName+' from ''F:/Data/BDL_BI_Test.csv'' 
    with(firstrow=2,FORMAT=''csv'',FIELDTERMINATOR='','',ROWTERMINATOR=''\n'')'
    exec(@QUERY2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 2012-03-13
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      相关资源
      最近更新 更多