2015-10-31 100 views
3

我有一个要求将大的2 GB CSV文件插入我的MS SQL数据库。大部分的行不需要插入。在进行批量插入时,我没有找到任何要过滤的行。我正在使用MS SQL批量插入命令来执行此操作。是否有任何选项可以在批量插入上过滤mySQL/MSSQL/Oracle上的行?MS SQL批量插入

BULK INSERT payroll.t_allowance 
    FROM 'f:\orders\lineitem.csv' 
    WITH 
     (
     FIELDTERMINATOR =' |', 
     ROWTERMINATOR =' |\n' 
    ); 
+0

@suchit您的编辑失败。当然,这使得代码变得很漂亮,但是把英文放在了顶部,并且把它弄糟了。 “没有找到任何可以使用的东西......”嗯? 'Builter',那是什么? – zipzit

+1

如何批量插入并删除不需要的行 – BICube

+0

在导入之前是否可以过滤行?要么使用脚本语言,要么使用type + find? –

回答

3

您可以使用OPENROWSETBULK选项:

SELECT * 
FROM OPENROWSET(BULK 'f:\orders\lineitem.csv', 
       FORMATFILE= 'f:\orders\format.xml') AS a 
WHERE ... 

format.xml可以在其中配置定界符,列名,文件终止等:https://msdn.microsoft.com/en-us/library/ms178129.aspx

0

使用OPENROWSET(BULK...)是要走的路,假设您不能预先过滤文件。

INSERT INTO table1 (col1, col2, ..., colN) 
SELECT col1, col2, ..., colN 
FROM OPENROWSET(BULK '<data_file_name>.txt', FORMATFILE = '<format_file_name>.xml') AS a 
WHERE ... 

作为一个附带的好处是,你可以选择使用功能和查找表文件转换数据,并添加连接到其他表进行过滤,但你必须牢记的性能影响。

INSERT INTO table1 (col1, col2, ..., colN) 
SELECT a.col1, a.col2, ..., a.colN 
FROM OPENROWSET(BULK '<data_file_name>.txt', FORMATFILE = '<format_file_name>.xml') AS a 
INNER JOIN ... 
ON ... 
LEFT JOIN ... 
ON ... 
WHERE ... 

Import Bulk Data by Using BULK INSERT or OPENROWSET(BULK...)

注意,使用OPENROWSET(BULK...)会要求您创建一个XML或非XML格式的格式文件。这两种文件格式都可能很难用手写入,并且容易出错。如果您可以从生成的文件开始并进行必要的修改,那么您的工作将变得更加轻松。使用bcp程序生成格式文件。首选XML格式(-x参数)。

bcp <table_or_view> format nul -f<format_file_name>.xml -x

Create a Format File

1

为了避免格式文件的复杂性,以及与其他一些权衡,你可以创建一个临时表,BULK INSERT临时表,并使用INSERT...SELECT加载目标表从临时表中。

-- Create a temporary staging table with the same column names and data types, but no indexes 
-- Alternatively, use CREATE TABLE 
-- When using a permanent table, use TRUNCATE TABLE 
SELECT * 
INTO #stage 
FROM payroll.t_allowance 
WHERE 1 = 0; 

-- Bulk load the staging table 
-- Use the TABLOCK hint to achieve minimally logged inserts 
BULK INSERT #stage 
FROM 'f:\orders\lineitem.csv' 
WITH (TABLOCK, FIELDTERMINATOR = ' |', ROWTERMINATOR = ' |\n'); 

-- Load the target table from the staging table 
INSERT INTO payroll.t_allowance 
SELECT s.* 
FROM #stage AS s 
WHERE...; 

-- Drop the staging table 
-- or use TRUNCATE TABLE for a permanent table 
DROP TABLE #stage;