我有一个包含多行数据的.csv文件(请参阅图片)
此数据由第三方提供,我无法更改格式。
我是BULK使用ms SQL服务器管理将这些数据插入SQL服务器表。
当我使用以下内容进行BULK插入时:
BULK INSERT #tempDERIVEDDATA
FROM 'C:\MyDownloads\Data.csv'
WITH
(FIRSTROW = 1,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '0x0a',
ERRORFILE = 'C:\MyDownloads\logfile.log')
GO
我似乎得到以下错误:
消息4832,级别16,状态1,行236批量加载:意外结束 在数据文件中遇到文件。 Msg 7399,Level 16,State 1,第236行OLE DB提供程序“BULK”用于链接服务器“(null)” 报告错误。提供商没有提供任何有关的信息 错误。消息7330,级别16,状态2,行236无法从中获取行 OLE DB提供程序“BULK”用于链接服务器“(null)”。
当最后一行是页脚行并指出文件中的行数被删除时,批量插入工作。所以我甚至不能删除那一行,因为他们正在努力做到这一点。
那么我想如果使用OPENROWSET函数并计算行数并将(#rows - 1)插入表中会怎么样?
所以我尝试了下面的方法来计算行数:
DECLARE @lastrow INT
SET @lastrow = (SELECT COUNT(*) FROM OPENROWSET(BULK 'C:\MyDownloads\DATA1.csv',
FORMATFILE = 'C:\MyDownloads\format.fmt',
MAXERRORS=10) AS ) - 1
SELECT @lastrow
选择的最后一行应该检索(#rows - 1)应该检索行数,但是我得到一个错误。
Msg 4832,Level 16,State 1,Line 230批量加载:意外结束 在数据文件中遇到了文件。 Msg 7399,Level 16,State 1, 第230行OLE DB提供程序“BULK”用于链接服务器“(null)” 报告错误。提供商没有提供任何有关的信息 错误。消息7330,级别16,状态2,行230无法从中获取行 OLE DB提供程序“BULK”用于链接服务器“(null)”。
之后我决定使用格式文件,而不是SINGLE_CLOB。这次没有错误,但文件在检索'341'时会检索'0'行。
如果有人可以提供协助,我将不胜感激。
答案 0 :(得分:0)
考虑使用openrowset。
create procedure [dbo].LoadData
(
@file nvarchar(200)=null
)
as
begin
declare @sql varchar(max)
set @sql='INSERT INTO DBO.Table
(
column1, column2
)
select column1
,column2
from openrowset(bulk N''' + @file +''',
formatfile = N''d:\xml\Table.xml'') as t1
where not column1 like (''Total'')'
print @sql
exec (@sql)
end
--- Table.xml
<?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="," MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="column1" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="2" NAME="column2" xsi:type="SQLNVARCHAR"/>
</ROW>
</BCPFORMAT>
答案 1 :(得分:0)
Hummm,我在2015年遇到了完全相同的问题。你是否偶然在CapIQ工作?无论如何,我最终创建了一个C#可执行文件并运行它来清理文件,然后运行Bulk Insert脚本来加载数据。我实际上保存了那个解决方案,因为我觉得有一天我会再次需要它。这是解决方案。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
string sourceDirectory = @"C:\ManagedCode\Downloads\";
try
{
var txtFiles = Directory.EnumerateFiles(sourceDirectory);
foreach (string currentFile in txtFiles)
{
//foreach (var currentFile in files)
{
var lines = File.ReadAllLines(currentFile);
//Just an example of changing the filename based upon the current name
var targetFile = Path.ChangeExtension(currentFile, "prod.txt");
File.WriteAllLines(targetFile, lines.Skip(1).Take(lines.Count() - 2));
//};
}
}
}
catch (Exception ex)
{
}
}
}
}
您可以使用Windows任务管理器在您选择的任何计划上运行此可执行文件(以及任何可执行文件)。
答案 2 :(得分:0)
使用一个宽列创建一个临时表,并将整个行插入整个文件的该列中,然后使用select + insert从临时表中进行选择,并在选择时通过分隔符分隔字段,并排除最后一行。最后,将临时表放入准备中以进行下一次导入。