2017-02-16 84 views
-1

我正在使用管道分隔的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结尾(如记事本++中所示),所以向导无法区分具有CRLF的行需要保留在记录中还是实际上是记录的结尾。

+0

你甚至谷歌呢? –

+0

@ rory.ap - 是的。如果您可以将我指向一个可以帮助我的网站,请这么做! – marky

+0

查看BULK INSERT命令。 – EMUEVIL

回答

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中访问以下两个选项。

使用openrowset使用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 
); 

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;