首页 文章

批量插入SQL Server中正确引用的CSV文件

提问于
浏览
44

我正在尝试导入一个正确引用的CSV文件,这意味着数据仅在包含逗号时引用,例如:

41, Terminator, Black
42, "Monsters, Inc.", Blue

我观察到第一行正确导入,但第二行错误以建议引用的逗号被视为字段分隔符 .

我见过这样的建议

SQL Bulk import from CSV

更改字段终止符

FIELDTERMINATOR ='“,”'

但是,我的CSV文件仅引用需要它的字段,因此我不相信该建议会起作用 .

SQL Server的BULK IMPORT语句可以导入正确引用的CSV文件吗?怎么样?

9 回答

  • 7

    不幸的是,SQL Server将引用的逗号解释为分隔符 . 这适用于BCP和批量插入 .

    来自http://msdn.microsoft.com/en-us/library/ms191485%28v=sql.100%29.aspx

    如果数据中出现终止符,则将其解释为终结符,而不是数据,并将该字符后的数据解释为属于下一个字段或记录 . 因此,请仔细选择终结器,以确保它们永远不会出现在您的数据中 .

  • 3

    还有另一种解决方案 .

    通过编辑fmt文件,将引号视为字段分隔符的一部分 .

    您可以查看此信息以获取更多信息:

    http://blogs.msdn.com/b/sqlserverfaq/archive/2010/02/04/how-to-remove-unwanted-quotation-marks-while-importing-a-data-file.aspx

    以上链接的摘录:

    删除引号的唯一方法是修改导入操作期间指定的列分隔符 . 这里唯一的缺点是,如果您检查要插入的数据,您将很快意识到每个列的列分隔符是不同的(上面突出显示的分隔符) .

    因此,要为每列指定不同的列分隔符,如果计划使用批量插入或BCP,则需要使用格式文件 . 如果为上述表结构生成格式文件,则如下所示:

    9.0
    3
    1       SQLCHAR       0       5       "\t"     1     FName              SQL_Latin1_General_CP1_CI_AS
    2       SQLCHAR       0       5       "\t"     2     LName              SQL_Latin1_General_CP1_CI_AS
    3       SQLCHAR       0       50      "\r\n"   3     Company            SQL_Latin1_General_CP1_CI_AS
    

    修改格式文件以表示每列的正确列分隔符 . 要使用的新格式文件如下所示:

    9.0
    4
    1       SQLCHAR       0       0     "\""      0     FIRST_QUOTE      SQL_Latin1_General_CP1_CI_AS
    2       SQLCHAR       0       5     "\",\""   1     FNAME               SQL_Latin1_General_CP1_CI_AS
    3       SQLCHAR       0       5     "\",\""   2     LNAME            SQL_Latin1_General_CP1_CI_AS
    4       SQLCHAR       0       50    "\"\r\n"  3     COMPANY          SQL_Latin1_General_CP1_CI_AS
    
  • 15

    确保已启用TextQualified选项并将其设置为 " .

  • 1

    我知道这是一个老话题,但是自SQL Server 2017以来这个功能现在已经实现 . 参数你're looking for is FIELDQUOTE= which defaults to '“' . 更多关于https://docs.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-2017

  • 7

    您还可以查看将OpenRowSet与CSV文本文件数据提供程序一起使用 .

    对于任何版本的SQL Server> = 2005,这应该是可能的,尽管您需要启用该功能 .

    http://social.msdn.microsoft.com/forums/en-US/sqldataaccess/thread/5869d247-f0a0-4224-80b3-ff2e414be402

  • 3

    我有同样的问题,我不想去SSIS路由,所以我找到了一个易于运行的PowerShell脚本,并在该特定字段中使用逗号处理引号的情况:

    PowerShell脚本的源代码和DLL:https://github.com/billgraziano/CsvDataReader

    这是一个解释用法的博客:http://www.sqlteam.com/article/fast-csv-import-in-powershell-to-sql-server

  • 2

    我've spent half a day on this problem. It'最好使用SQL Server导入和导出数据向导导入 . 该向导中有一个设置可以解决此问题 . 详细截图:https://www.mssqltips.com/sqlservertip/1316/strip-double-quotes-from-an-import-file-in-integration-services-ssis/谢谢

  • 26

    我遇到了同样的问题,数据只是偶尔会引用一些文字 . 我的解决方案是让BULK LOAD导入双引号,然后对导入的数据运行REPLACE .

    例如:

    批量插入“F:\ Data \ Map \ CodePointOpen \ Data \ CSV \ ab.csv”中的CodePoint_tbl(FIRSTROW = 1,FIELDTERMINATOR =',',ROWTERMINATOR ='\ n');

    更新CodePoint_tbl设置Postcode = replace(邮政编码,'“','')其中charindex('”',Postcode)> 0

    为了减少编写REPLACE脚本的痛苦,只需从以下结果中复制并粘贴您需要的内容:

    select C.ColID, C.[name] as Columnname into #Columns
    from syscolumns C
    join sysobjects T on C.id = T.id
    where T.[name] = 'User_tbl'
    order by 1;
    
    declare @QUOTE char(1);
    set @QUOTE = Char(39);
    select 'Update User_tbl set '+ColumnName+'=replace('+ColumnName+','
     + @QUOTE + '"' + @QUOTE + ',' + @QUOTE + @QUOTE + ');
    GO'
    from #Columns
    where ColID > 2
    order by ColID;
    
  • 0

    根据CSV格式规范,我没有正确实施't think it matters if data is correctly quoted or not, as long as it adheres to specification. Excessive quotes should be handled by the parser, if it' . FIELDTERMINATOR 应为逗号, ROWTERMINATOR 为行尾 - 这表示标准CSV文件 . 您是否尝试使用这些设置导入数据?

相关问题