使用SqlBulkCopy并获取此异常:
从bcp客户端收到colid 30的无效列长度.
几个小时以来,我一直在撞击这个.我知道哪一行有问题,但我不知道哪个列"colid 30".数据表中有178列.所有值似乎都是正确的,我没有看到任何值比我的数据库中的任何列数据类型更长.
该数据库包含房产列表,目前有超过300万条记录,所有记录都很好.
有没有办法确定colid 30是什么?或者有没有办法查看bcp提交给数据库的实际SQL?
使用 VS 2013 ASP.NET MVC 5 Web 项目和单独的 Azure 托管 SQL Server 数据库进行开发。
底部是我来自 Visual Studio 2013 的所有错误信息。我缩小了问题的范围,找到了指向 Microsoft 问题描述的链接,但没有解决方案。我正在使用数据库优先和实体框架 6 进行开发。ASP.NET 4 MVC 和 Razor。我连接到 SQL Azure 数据库 - 我认为这是失败的原因我已经检查了 Azure 网站等的日志
我已将文本文件(已上传到 APP_DATA)分隔开,然后将其加载到 DataTable 中,然后使用 SQL-Bulk Copy 将内容转储到 Azure 数据库中。只要我的文件只包含几百条记录,一切都可以 100% 正常工作。但我需要插入大约 200,000 行的 20MB 文件。当我尝试大文件时,在 ASP.NET 执行批量复制时出现错误。无论我为批量大小等设置了什么,它每次都在 4000 行标记附近。我已经用尽了所有选择,最后,我什至尝试将 Azure 数据库从免费网络扩展到企业。我也尝试扩大网站。这是代码:
public void BatchBulkCopy(DataTable dataTable, string DestinationTbl, int batchSize,int identity)
{
try {
// Set the timeout.
System.Diagnostics.Debug.WriteLine("Start SQL Bulk Copy");
using (SqlBulkCopy sbc = new SqlBulkCopy("Server=tcp:eumtj4loxy.database.windows.net,1433;Database=AscWaterDB;User …Run Code Online (Sandbox Code Playgroud) 为了给出一些上下文,我目前正在Amazon RDS上运行一个SQL Server 2012实例,而且我不得不两次移动到更大的实例.第一次SQLAzureMW是要走的路,但当时没有一张表那么大.第二次,SQLAzureMW总是使用大表(超过5 GB的几个)在bcp命令上超时源服务器.同样,SSIS导入/导出向导也超时.我发现源服务器始终是问题所以我尝试将实例的类从m1.medium增加到m1.xlarge无济于事,源服务器仍然总是超时,然后在大表上取得任何重大进展.
最后,我最终编写了自己的.NET程序,只在大型源表上运行"SELECT*FROM [table] ORDER BY [id] OFFSET {0} ROWS",并将结果推送到目标服务器上的SQLBulkCopy中.源服务器再次超时,但我在一个循环中包装了try和catch语句,这将简单地从SQLBulkCopy的最后一点恢复查询.话虽如此,我对这个解决方案并不十分兴奋.
我正在考虑围绕Microsoft.SqlServer.Management.Smo.Transfer类构建一个解决方案,但我担心可能会出现与源代码连接断开无法恢复相同的问题.
我更倾向于开箱即用的解决方案,就像SQLAzureMW在表格过大之前我希望SSIS导入导出向导一样.一定有更好的方法.
我正在尝试使用fastmember(Fastmember NuGet)扩展和sqlbulkcopy 将某个自定义对象列表Bulkinsert到我的数据库中.但是它给了我以下错误:
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: Cannot insert the value NULL into column 'functionblockId', table '\path...\DBFHX.MDF.dbo.connections'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Run Code Online (Sandbox Code Playgroud)
码:
private void insertConnection(functionblock functionblock)
{
using (var bcp = new SqlBulkCopy(db.Database.Connection.ConnectionString))
{
foreach (connection item in functionblock.connections)
{
item.functionblockId = 1;
}
using (var creader = ObjectReader.Create(functionblock.connections, "step", "transition","steptotrans", "functionblockId"))
{
bcp.DestinationTableName = "connections";
bcp.WriteToServer(creader);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用Model First,Entity Framework生成了下表: …
我试图从xml文件中读取值,然后使用bulkcopy将数据插入到我的数据库中.
我正在使用一个自定义类:
class Customer
{
public int CustomerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int ShowsNumber { get; set; }
public int VisitNumber { get; set; }
public int Cancellation { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我读了这样的数据:
List<Customer> customersList =
(
from e in XDocument.Load(file).Root.Elements("cust")
select new Customer
{
CustomerID = (int)e.Attribute("custid"),
FirstName = (string)e.Attribute("fname"),
LastName = (string)e.Attribute("lname"),
ShowsNumber = (int)e.Attribute("count_noshow"),
VisitNumber = (int)e.Attribute("count_resos"),
Cancellation = (int)e.Attribute("count_cancel"),
}).ToList(); …Run Code Online (Sandbox Code Playgroud) 下面是我用来将数据从临时表 dataTable 批量复制到 Oracle 数据库中的 destTable 的代码。dataTable 有大约 200 万条记录。
using (OracleBulkCopy bulkCopy = new OracleBulkCopy(VMSDATAConnectionString))
{
try
{
foreach (OracleBulkCopyColumnMapping columnMapping in columnMappings)
bulkCopy.ColumnMappings.Add(columnMapping);
bulkCopy.DestinationTableName = destTableName;
//bulkCopy.BatchSize = dataTable.Rows.Count;
//bulkCopy.BulkCopyTimeout = 100;
int defaultSize = 5000;
int.TryParse(ConfigurationManager.AppSettings["OracleBulkCopyBatchSize"], out defaultSize);
bulkCopy.BatchSize = defaultSize;
int timeOut = 100;
int.TryParse(ConfigurationManager.AppSettings["OracleBulkCopyTimeout"], out timeOut);
bulkCopy.BulkCopyTimeout = timeOut;
Console.WriteLine("Bulk insert from {0} to {1} started at: {2}\r\nBatchSize : {3}, BulkCopyTimeout : {4} ", dataTable.TableName, destTableName, DateTime.Now.ToString("HH:mm:ss"), bulkCopy.BatchSize.ToString(), bulkCopy.BulkCopyTimeout.ToString());
bulkCopy.WriteToServer(dataTable);
Console.WriteLine("Bulk insert from {0} to …Run Code Online (Sandbox Code Playgroud) 我们正在使用 C# 组件执行批量插入操作。
这是代码:
using (SqlCommand sqlCommand = new SqlCommand("SET XACT_ABORT ON", _sqlConnection))
{
sqlCommand.SafeExecuteNonQuery();
}
var sqlBulkCopy = new SqlBulkCopy(_sqlConnection, bulkCopyOptions, null);
sqlBulkCopy.WriteToServer(table);
Run Code Online (Sandbox Code Playgroud)
出现以下错误:
此操作与此事务上的另一个待处理操作冲突。操作失败。
堆栈跟踪:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlBulkCopy.RunParser(BulkCopySimpleResultSet bulkCopyHandler)
at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinuedOnSuccess(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults, …Run Code Online (Sandbox Code Playgroud) 我正在尝试将数据从“csv”文件传输到 SQL 数据库。是否可以在默认情况下映射一些不存在于“csv”文件中的字段?如下图所示:
bulkCopy.ColumnMappings.Add("Destenition_column_name", "constant_value");
感谢提前!
如果需要以流式方式从SqlServer 读取数据,可以使用一些功能来实现。例如使用SqlDataReaderwith CommandBehavior.SequentialAccess,特别是当需要访问二进制列数据时,有以下方法GetStream(int):
var cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = @"select 0x0123456789 as Data";
using (var dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
dr.Read();
var stream = dr.GetStream(0);
// access stream
}
Run Code Online (Sandbox Code Playgroud)
但是,当需要使用向SqlServer 提供数据时SqlBulkCopy,特别是需要将流作为二进制列的数据源提供时,如何以相反的方向流式传输数据呢?
我尝试跟随
var cmd2 = new SqlCommand();
cmd2.Connection = connection;
cmd2.CommandText = @"create table #Test (ID int, Data varbinary(max))";
cmd2.ExecuteNonQuery();
using (SqlBulkCopy sbc = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null))
{
sbc.DestinationTableName = "#Test";
sbc.EnableStreaming = true;
sbc.ColumnMappings.Add(0, "ID"); …Run Code Online (Sandbox Code Playgroud) 我有以下代码..它实际上使用 SQLBulkCopy 将数据插入到目标中。由于死锁,此代码在源 SQL 服务器中经常失败。仅供参考,当我们执行批量复制时,正在复制的表可以使用(我的意思是一些插入/选择将运行)。
这是导致问题还是“TABLOCK”提示有什么关系?根据我的理解 TABLOCK 只获取共享锁,应该不成问题。
using (var reader = srcConnection.ExecuteReader($"select * from [{DatabaseName}].[{schemaName}].[{tableName}]"))
{
const SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.KeepNulls | //Do not replace nulls with defaults in destination
SqlBulkCopyOptions.KeepIdentity;
//Use the identity values from source, do not generate identities in destination.
using (var bcp = new SqlBulkCopy(dstConnection.ConnectionString, bulkCopyOptions))
{
const int threeMinutes = 60*3;
bcp.BulkCopyTimeout = threeMinutes; //Timeout is for a single batch
bcp.BatchSize = 5000;
bcp.DestinationTableName = $"[{DestinationDatabaseName}].[{schemaName}].[{tableName}]";
bcp.EnableStreaming = true;
foreach …Run Code Online (Sandbox Code Playgroud) sqlbulkcopy ×10
c# ×7
sql-server ×5
ado.net ×2
sql ×2
.net ×1
asp.net-mvc ×1
azure ×1
bulkinsert ×1
csv ×1
deadlock ×1
fastmember ×1
idatareader ×1
linq ×1
linq-to-xml ×1
mapping ×1
memory-leaks ×1
oracle ×1
smo ×1
ssis ×1