使用OPENROWSET跳过最后一行

时间:2015-01-30 05:43:58

标签: sql-server csv openrowset nocount

我正在使用以下命令对供应商提供的.csv文件进行相当直接的导入(我稍微简化了一下):

插入...来自OPENROWSET(批量' CSV文件名',格式文件=' XMLFormatFileName',FIRSTROW = 2,MAXERRORS = 0)AS BulkLoadFile

CSV文件格式如下所示(您可能需要点击查看图片,因为我是StackOverflow的新手,我还不能直接发布图片):

http://i.stack.imgur.com/qZMwV.jpg

我的问题是带有计数的最后一行......导致导入失败!

FYI>>>是的我知道你可以使用" SET NOCOUNT ON;"但是我没有生成这个文件,所以这不是一个选项。

现在我打开文件并删除最后一行,然后在导入之前重新保存。 (注意:我也删除了绿色显示的前2行,因为我已经在文件中,但是前两行不是问题,因为我可以使用FIRSTROW = 4切换跳过这些行。)

所以我的问题是:

有没有办法跳过最后一行?

OR

有没有办法获得行数并且可能使用LAST ROW开关?即最后一行=来自myCSVfile的计数(*)

OR

因为它始终像"总计:"反正有没有添加WHERE子句?即第一栏中的WHERE值与“总计:%'

”不同

OR

SSIS会更好地处理这件事吗?如果是这样,我可以将此导入例程移到SSIS。

提前致谢...我期待真正实现自动化,并且每次导入时都不必打开此文件(一天多次)。

D3Y

3 个答案:

答案 0 :(得分:0)

我看到两个选项:

  1. 将数据插入临时表,清除不需要的行,然后插入到final(生产表)中。这可以仅使用T-SQL来完成。

  2. 使用SSIS包(特定于数据流任务),您可以使用条件拆分来过滤掉不需要的行。例如https://www.simple-talk.com/sql/ssis/ssis-basics-using-the-conditional-split/

答案 1 :(得分:0)

找到了替代方法......

我使用 MAXERRORS = 0

如果我假设(是的,我知道这里有关于假设的笑话),我将有1(预期)错误与最后一行有关,我可以使用 MAXERRORS = 1 ,我的数据导入就好了。最后一行(总计:xxxx)被导入到我的表中,但是当我在更新管道中进一步使用时,我可以忽略该行。

另外值得注意的是...... 如果没有指定max_errors,默认值是10 ,因此我甚至可以通过甚至不使用MAXERRORS开关来避免这种情况......去图。

背景:MSDN(msdn.microsoft.com/en-us/library/ms188365.aspx)指定在取消批量导入操作之前数据中允许的最大语法错误数。批量导入操作无法导入的每一行都将被忽略并计为一个错误

答案 2 :(得分:0)

我刚刚创建了一个openrowset命令,该命令位于我需要知道最后一行的命令之前,并将其指向相关文件。将formatfile设置为只有delineator(一列),设置rowterminator(在本例中为\ n)。这是我非常简单的格式文件:

<?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="\n" MAX_LENGTH="10000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Column0" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

然后我使用了减去1 的计数

DECLARE @File VARCHAR(200);

SET @File = '''Dir\path\';
SET @File += 'filename.txt''';

DECLARE @SQL4Rows NVARCHAR(max)

SET @SQL4Rows = (
        'select count (*) FROM OPENROWSET(BULK 
        ' + @file + 
        ', 
        FORMATFILE = 
        ''\\fullformatfilepath_rowCountOnly.xml'') T'
        )

DECLARE @SQL4RowsTable AS TABLE (col INT)

INSERT INTO @SQL4RowsTable
EXECUTE sp_executesql @SQL4Rows

DECLARE @Rows VARCHAR(6)

SET @Rows = (
        SELECT *
        FROM @SQL4RowsTable
        ) - 1 --the last line of the files is the row count, thus the minus 1

DECLARE @SQL4Results NVARCHAR(max) --main sql to get results

SET @SQL4Results = (
        '
SELECT column,etc,
INTO #inlinetemp
FROM OPENROWSET(BULK ' + @File + 
        ', 
        FORMATFILE = 
        ''\\fullformatfilepath.xml'',LASTROW = ' + @Rows + 
        ') T
WHERE column = ''la''
SELECT DISTINCT columns
FROM #inlinetemp ab
LEFT JOIN db..tblaccounts a
    ON ab.accountnumber = a.AccountNumber
ORDER BY column asc '
        )

EXECUTE sp_executesql @SQL4Results