SSMS - 将CSV文件读入表格

时间:2017-02-16 20:46:10

标签: sql-server regex csv ssms

我正在使用竖线分隔的CSV,其中一些记录在其中一列中有回车符,因为它是如何被提取的。

示例:

Jane|Ward|3     |1          |1     |0     |0     |||3210007      
Sam|Anderson|4     |1          |1     |0     |0     |||3210008      
Andy|Smithson    |1     |1          |0     |0     |0     ||

|        
Henry|Johnson     |1     |1          |1     |0     |1     |Elementary School||900196 
Mary|Smith     |2     |1          |1     |0     |0     |||97 Ford 
Chris|Jones     |3     |1          |1     |0     |0     |||900341       
Allen|Bender    |1     |33fg5      |asdd3 |0     |0     ||

|        
Amy|Peterson|3     |1          |1     |0     |0     |||3210007      

记录都有10列,所以每个都有9个管道。在这个例子中,Andy Smithson和Allen Bender的记录在第9栏中有回车。如果任何记录确实有回车符,则它们将始终位于第9列。

我已经想过如何在Notepad ++中使用正则表达式来“清理”记录,但是我正在处理一个有近70k行的文件,所以我想尝试尽可能地自动化这个,显然。

有没有办法以某种方式将这样的文件读入表中?

我将在SSMS 2008及更高版本的版本中执行此操作。

[编辑] 我在SSMS导入向导中尝试过这个。它不会那样工作,因为每一行都以CRLF结尾(如Notepad ++中所示),因此当带有CRLF的行需要保留在记录中或实际上是记录的结尾时,向导无法区分。

1 个答案:

答案 0 :(得分:0)

您最好的选择是使用格式文件,以便它不会在RowTerminator的早期中断,并一直持续到FieldTerminator

您的数据的示例xml格式文件如下所示:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <RECORD>
    <FIELD ID="1" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="2" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="3" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="4" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="5" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="6" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="7" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="8" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="9" xsi:type="CharTerm" TERMINATOR= '|' COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
    <FIELD ID="10" xsi:type="CharTerm" TERMINATOR='\r\n'  COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  </RECORD>
  <ROW>
    <COLUMN SOURCE="1" NAME="Firstname" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="2" NAME="Lastname" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="3" NAME="Column3" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="4" NAME="Column4" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="5" NAME="Column5" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="6" NAME="Column6" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="7" NAME="Column7" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="8" NAME="Column8" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="9" NAME="Column9" xsi:type="SQLVARYCHAR"/>
    <COLUMN SOURCE="10" NAME="Column10" xsi:type="SQLVARYCHAR"/>
  </ROW>
</BCPFORMAT>

并像这样使用它:

使用bcp

bcp testdb.dbo.target_table IN D:\BCP\bulk_import_file.txt -f D:\BCP\format_file.xml -T

注意:对于以下两个选项,需要从sql server访问文件路径。

使用bulk insert

bulk insert dbo.target_table
  from '...\bulk_import_file.txt'
  with (
    formatfile = '...\format_file.xml'
  , firstrow   = 1 -- set to 2 if it has headers
  --, lastrow    =  /* if you need to skip extra lines at the end */
  , maxerrors  = 0
  , tablock
  );

使用openrowset

select *
from openrowset (
  bulk '...\bulk_import_file.txt'
  , formatfile = '...\format_file.xml'
  , firstrow   = 1 -- set to 2 if it has headers
  --, lastrow    =  /* if you need to skip extra lines at the end */
  , maxerrors  = 0
  ) as o;