BULK INSERT有两个行终止符

时间:2015-01-01 11:37:20

标签: sql sql-server tsql bulkinsert bcp

我正在尝试导入一个文本文件,因此结果只是一列的单独行中的单词。 例如文字:

  

'你好妈妈,

     

我们再次见面'

应该提供5条记录:

'Hello' 
'Mom,'
'we' 
'meet' 
'again'

我尝试使用BULK INSERTROWTERMINATOR = ' '完成此操作,但将new line视为terminator并且我获得'Mom,we'时出现问题其中一个结果。

据我所知,没有办法将second ROWTEMRMINATOR添加到BULK INSERT(是吗?)。 您知道如何达到上述结果的最佳方法是什么?

该文件无法在SQL Server之外进行预处理,并且该方法对于数百个具有单词行的文件非常有用,这些文件在不同时间导入,而不仅仅是一次。

1 个答案:

答案 0 :(得分:2)

假设:

  

无法在SQL Server外部预处理文件

选项1

为什么不使用OPENROWSET(BULK...)?这将允许您导入/插入(负责行终止符),同时拆分(负责字段终止符)。根据您是否可以创建Format File,它应该类似于以下内容之一:

格式文件=拆分每一行

INSERT INTO dbo.TableName (ColumnName)
  SELECT split.SplitVal
  FROM   OPENROWSET(BULK 'path\to\file.txt',
                    FORMATFILE='Path\to\FormatFile.XML') data(eachrows)
  CROSS APPLY SQL#.String_Split(data.eachrow, N' ', 2) split;

无格式文件=将整个文件拆分为单行

INSERT INTO dbo.TableName (ColumnName)
  SELECT split.SplitVal
  FROM   OPENROWSET(BULK 'path\to\file.txt', SINGLE_CLOB) data(allrows)
  CROSS APPLY SQL#.String_Split(
                                REPLACE(data.allrows, NCHAR(10), N' '),
                                N' ',
                                2 -- remove empty entries
                               ) split;

注意:

  • 对于这两种方法,您需要使用字符串拆分器。基于SQLCLR的分离器是最快的,在上面的示例中,我使用了SQL#库中的一个(我创建了它,但String_Split函数在免费版本中可用)。你也可以自己写。如果你自己编写并使用格式文件,那么允许多个分割字符可能是个好主意,这样你就可以同时传入" "和" \ n"并摆脱REPLACE()

  • 如果您可以编写自己的SQLCLR字符串拆分器,那么编写一个接受@FilePath的输入参数的SQLCLR存储过程,读取文件,进行拆分以及吐出单个列的多行:

    INSERT INTO dbo.TableName(ColumnName)
      EXEC dbo.MySQLCLRproc(N'C:\path\to\file.txt');
    
  • 如果您不使用(或不能使用)格式文件,请务必使用正确的" SINGLE _"您可以选择SINGLE_CLOB(对于标准ASCII文件返回VARCHAR(MAX))或SINGLE_NCLOB(对于Unicode文件返回NVARCHAR(MAX))。

  • 即使您可以创建格式文件,可能更有效地将整个文件作为单个字符串拉入,具体取决于文件的大小,因为分割大字符串可以相当快速地完成并且是单个函数调用,而数千个短行的文件将是数千个函数调用,这些函数调用也很快,但可能不比单个调用快1000倍。但是如果文件是1 MB或更大,那么我可能仍然会选择执行格式文件并处理尽可能多的短行。

选项2

如果通过"预处理"你的意思是改变了,但是简单地读取它们并从SQL Server外部插入数据没有限制,你应该编写一个小的.NET应用程序来读取行,分割行,并通过调用存储来插入数据接受表值参数(TVP)的过程。我在S.O.的另一个答案中详述了这种方法:

How can I insert 10 million records in the shortest time possible?

这可以编译为控制台应用程序,并在批处理(即 .CMD / .BAT )脚本中使用,甚至可以安排为Windows任务。