0

我正在使用以下命令对供应商提供的 .csv 文件进行相当直接的导入(我已将其缩写了一点):

插入... 从 OPENROWSET (Bulk 'CSVFileName', FORMATFILE ='XMLFormatFileName', FIRSTROW = 2, MAXERRORS = 0 ) AS BulkLoadFile

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

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

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

仅供参考 >>> 是的,我知道你可以使用“SET NOCOUNT ON;” 但我不生成这个文件,所以这不是一个选项。

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

所以我的问题是:

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

或者

有什么方法可以获取行数并可能使用 LAST ROW 开关?即最后一行 = 来自 myCSVfile 的计数(*)

或者

由于它总是以“Total:”开头,所以无论如何要添加 WHERE 子句?即第一列中的 WHERE 值不像 'Total:%'

或者

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

在此先感谢...我期待真正实现自动化,而不必在每次导入时都打开这个文件(一天多次)。

D3Y

4

3 回答 3

0

找到解决方法...

我正在使用MAXERRORS = 0

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

另外值得注意的是…… 如果未指定 max_errors,则默认值为 10,因此我什至可以通过不使用 MAXERRORS 开关来避免这种情况……看图。

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

于 2015-01-30T17:09:36.970 回答
0

我看到两个选项:

  1. 将数据插入临时表,清理不需要的行,然后插入最终(生产表)。这只能使用 T-SQL 来完成。

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

于 2015-01-30T10:50:46.360 回答
0

我刚刚创建了一个 openrowset 命令,该命令位于我需要知道最后一行的命令之前,并将其指向相关文件。将格式文件设置为只有轮廓符(一列),设置行终止符(在本例中为 \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
于 2017-05-18T17:24:50.130 回答