【问题标题】:Skip LAST Line with OPENROWSET使用 OPENROWSET 跳过最后一行
【发布时间】:2015-01-30 05:43:58
【问题描述】:

我正在使用以下命令(我稍微简化了一点)对供应商提供的 .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

【问题讨论】:

    标签: sql-server csv openrowset nocount


    【解决方案1】:

    我看到两个选项:

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

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

    【讨论】:

    • 感谢您的反馈,但这些解决方案无法解决我的问题...由于最后一行,我无法导入文件(到临时表或生产表)。
    • 您是否遇到任何错误?根据您提供的信息,我没有看到最后一行无法导入然后删除(未移动)到最终/生产表的任何障碍。
    • ivankristof,你是对的......这更多是关于我错误地使用了 MAXERRORS 开关。感谢您的反馈!
    【解决方案2】:

    找到解决方法...

    我使用的是 MAXERRORS = 0

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

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

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

    【讨论】:

      【解决方案3】:

      我刚刚创建了一个 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
      

      【讨论】:

        猜你喜欢
        • 2013-12-10
        • 2020-06-20
        • 2015-01-20
        • 2015-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-24
        相关资源
        最近更新 更多