我正在使用以下命令对供应商提供的.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
答案 0 :(得分:0)
我看到两个选项:
将数据插入临时表,清除不需要的行,然后插入到final(生产表)中。这可以仅使用T-SQL来完成。
使用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