为什么async在单个事务上针对不相关的表并行运行多个 SqlBulkCopy 插入看起来就像串行运行一样?
我有一些代码正在计算和存储大量数据。计算是预先完成的,因此代码的存储部分得到了要存储的一大堆数据。
我的数据库写入正在完成,SqlBulkCopy.WriteToServerAsync一般来说,它可以很好地完成工作。
我需要存储6个与业务相关的表,但与SQL无关。因此,我对它们的写入需要在一个事务中进行,以便任何一个写入上的错误都会恢复所有其他写入上的写入。
该代码的性能相当关键,因此我希望能够并行运行 BulkInsert。没有 FKey 或任何其他与之交互的表(数据完整性由代码管理),因此我看不出有任何理由认为这是不可能的。
我以为我知道如何编写所有代码并且能够使其全部正常工作,但是有一个我不明白的奇怪的性能下降:
很高兴提供您想要的实际代码位,但这已经是一个很长的 Q,并且代码会很长到 0。如果你确实想看什么,LMK。
我可以写:
“按顺序批量插入到每个表中,全部在单个事务中”。
new SqlConnection()and .BeginTransaction(),foreach翻了6张桌子,await InsertToTable(transaction)每张桌子都移动foreach到下一张桌子。foreach结束时我.Commit()进行事务并关闭连接。“按顺序批量插入每个表,每个表都有一个新的连接和事务。”
foreach遍历了 6 个表,并且await InsertToTable()每个表在foreach移动到下一个表之前。InsertToTable()调用中,我都会打开一个新的SqlConnectionand BeginTransaction,然后在从方法返回之前打开.Commit()一个 and 。.Close()当涉及可空列时,我遇到了使用SqlBulkCopy的问题.听起来像SqlBulkCopy不知道如何处理可空列并在遇到零长度列时抛出非法大小错误.错误是"从bcp客户端收到无效的列长度..."
我想知道处理这个问题的最佳做法是什么.这似乎是一个很好的论坛帖子,描述了这个问题以及如何解决它来阅读csv文件.
我认为我的情况非常简单.我需要将一个未知的数据从一个数据库表移动到另一个数据库.对我来说更简单的答案是在sql server中使用SSIS/DTS或链接服务器,但是客户希望应用程序进行数据移动.
是否有一个已知的工作可以用于这个或更好的流动解决方案来移动可空字段的数据?
//access db
string src_db = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\SourceDB.mdb;Jet OLEDB ";
//sql db
string dest_db = @"Data Source=.\TEST;Initial Catalog=testdb;User Id=user;Password=password;";
string sql = "";
OleDbConnection sdb = new OleDbConnection( src_db );
OleDbCommand cmd = new OleDbCommand( sql, sdb );
OleDbDataReader rs = null;
SqlConnection db = new SqlConnection( dest_db );
SqlCommand clear = null;
SqlBulkCopy bulk_load = null;
// Read in the source table
sql = "select * from someTable";
sdb.Open();
cmd = new …Run Code Online (Sandbox Code Playgroud) 我想将大量数据从F#传输到SQL表.基本上我的F#代码创建了一个包含三列(UserID, ProductID and price)和N行的矩阵.我想"复制/掌握它"到数据库中我尝试了几个选项,但最后,从F#传输数据真的很慢(10000行左右大约一小时).
感谢前一个问题的答案如何在F#中包含存储过程,解决此问题的一个有趣方法是使用SqlBulkCopy.
SqlBulkCopy需要一个数据库类型的WritetoServer方法,但我没有找到任何现有的代码或简单的方法将矩阵转换为数据库.你有什么建议或想法吗?
我已经按照这个线程C#import excel filesheet到sql数据库错误的答案,并能够将Excel数据导入SQL Server数据库.我唯一的问题是导入仅在从开发机器本地运行网站时起作用,但在将站点部署到IIS后,我在尝试从excel导入数据时出现以下错误.

我正在从 Excel 文件或 CSV 读取数据。我获取这些数据并创建一个数据表。然后我将该数据表与从原始数据库创建的数据表合并。合并有效,我已经整理了所有数据类型和列名。我有很多链接,但大多数都归结为数据类型和列名/列文本大小写。
没有错误。一切顺利。我试图批量复制的数据表在 VS 表查看器中是正确的。当我签入 SQLExpress 时,没有进行任何更改。我正在使用与项目其余部分相同的连接字符串(行删除、添加、编辑等)。
dt.Merge(dtnew)
Using destinationConnection As SqlConnection = _
New SqlConnection(sConnectionString)
destinationConnection.Open()
' Set up the bulk copy object.
' The column positions in the source data reader
' match the column positions in the destination table,
' so there is no need to map columns.
Using bulkCopy As SqlBulkCopy = _
New SqlBulkCopy(destinationConnection)
bulkCopy.DestinationTableName = _
"dbo.TableName"
Try
' Write from the source to the destination.
bulkCopy.WriteToServer(dt)
Catch ex As Exception …Run Code Online (Sandbox Code Playgroud) 这对我来说没有任何意义,但也许有眼睛更敏锐的人可以发现问题.
我有一个使用FileSystemWatcher的Windows服务.它处理一些文件并将数据上传到MSSQL数据库.它在我的机器上完全正常工作 - 与Visual Studio分离(即不调试)并作为服务运行.如果将这个已编译的代码复制到我们的服务器,并让它指向同一个数据库,甚至是相同的文件(!),我每次都会收到此错误:
System.InvalidOperationException: Invalid operation. The connection is closed.
at System.Data.SqlClient.SqlConnection.GetOpenTdsConnection()
at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinuedOnError(Boolean cleanupParser)
at System.Data.SqlClient.SqlBulkCopy.<>c__DisplayClass30.<CopyBatchesAsyncContinuedOnSuccess>b__2c()
at System.Data.SqlClient.AsyncHelper.<>c__DisplayClass9.<ContinueTask>b__8(Task tsk)
Run Code Online (Sandbox Code Playgroud)
我已经尝试将我的本地代码指向服务器的文件,它工作正常..Net 4.5.1在两台机器上.服务都在同一个域用户下运行.令人费解.也许我对SqlBulkCopy.WriteToServerAsync()有些不了解的东西?它会自动共享连接吗?它是否在通话之间关闭?这是相关的代码:
private static void ProcessFile(FileInfo fileInfo)
{
using (var bulkCopy = new SqlBulkCopy("Data Source=myserver;Initial Catalog=mydb;Persist Security Info=True;User ID=myusr;Password=mypwd;")
using (var objRdr = ObjectReader.Create(ReadLogFile(fileInfo)
.Where(x => !string.IsNullOrEmpty(x.Level)),
"Id", "AppId", "AppDomain", "AppMachine",
"LocalDate", "UtcDate", "Thread", "Level", "Logger", "Usrname",
"ClassName", "MethodName", "LineNo", "Message", "Exception",
"StackTrace", "Properties"))
{
bulkCopy.DestinationTableName = "EventLog";
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.EnableStreaming = true;
bulkCopy.BatchSize = AppConfig.WriteBatchSize;
bulkCopy.WriteToServerAsync(objRdr).ContinueWith(t …Run Code Online (Sandbox Code Playgroud) 我正在使用 anSqlBulkCopy将一百万条记录(每条记录大约有 10 列)的内容插入datatable到数据库表中。当我更改批量大小属性 ( bulkCopy.BatchSize) 时,我在批量复制期间看到一些不稳定的值。
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConn.ConnectionString, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.UseInternalTransaction | SqlBulkCopyOptions.CheckConstraints))
{
bulkCopy.DestinationTableName = destinationTableName;
bulkCopy.BatchSize = 100000;
bulkCopy.BulkCopyTimeout = 1800;
if (matchingColumns != null || matchingColumns.Count > 0)
foreach (KeyValuePair<string, string> kv in matchingColumns)
bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(kv.Key, kv.Value));
bulkCopy.WriteToServer(dt);
}
Run Code Online (Sandbox Code Playgroud)
当我不使用批量大小时,该过程在 7 分钟内完成。然后我将批量大小设置为100,000,时间在5:30左右,然后我将其设置为50,000,时间增加到10分钟。
我想知道批量大小对 INSERT 速度的影响。一般来说,它会让事情变得更快还是更慢?
因此,我向一位高级开发人员寻求帮助,以解决与事务范围相关的问题,他来到我的办公桌前,在 SqlBulkCopy 上使用了不同的重载,对于 SqlBulkCopyOptions 参数,他做了如下所示的操作:
SqlBulkCopyOptions options = (SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints);
Run Code Online (Sandbox Code Playgroud)
它现在有效,但我不明白bitwise or这里的意思。我以为我对它有一些了解,从来没有真正使用过它,但是这个用法让我摸不着头脑。是的,我没有要求我的前辈向我解释它。我希望有人能帮助我理解该声明的含义。网上的大多数按位或示例都带有一些数字,我得到了(我认为),但是这个?
我的问题是我面临
ProgrammingError: copy_from 不能与异步回调一起使用。
在尝试copy_from没有异步连接时。必须说明的是,我正在从芹菜任务创建连接。有人可以告诉我 sqlalchemy 或 celery 或任何强制我的 psycopg2 连接表现得像异步的线索吗?
conn = psycopg2.connect(con_string)
conn.async
>>0
cur = conn.cursor()
data = BytesIO()
data.write('\n'.join(['Tom\tJenkins\t37',
'Madonna\t\N\t45',
'Federico\tDi Gregorio\t\N']))
data.seek(0)
curs.copy_from(data, 'test_copy')
Run Code Online (Sandbox Code Playgroud) 我有很多数据表可批量插入数据库表中。由于尺寸较大,一张表需要5分钟才能完成插入。2张桌子花了我10分钟
static void Main(string[] args)
{
DataTableBulkInsert(DataTable1);
DataTableBulkInsert(DataTable2);
}
public static void DataTableBulkInsert(DataTable Table){
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(myConnection);
sqlBulkCopy.DestinationTableName = "dbo.DatabaseTable";
myConnection.Open();
sqlBulkCopy.WriteToServer(Table);
myConnection.Close();
}
Run Code Online (Sandbox Code Playgroud)
我现在正在尝试对批量插入执行异步操作,但是既没有插入任何数据,也没有给我错误。如何捕获异常?
static void Main(string[] args)
{
var insert1 = Task.Run(async () => await DataTableBulkInsert(DataTable1);
var insert2 = Task.Run(async () => await DataTableBulkInsert(DataTable2);
Task.WhenAll( insert1, insert 2);
}
public static async Task<Boolean> DataTableBulkInsert(DataTable Table)
{
try
{
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(myConnection);
sqlBulkCopy.DestinationTableName = "dbo.DatabaseTable";
myConnection.Open();
await sqlBulkCopy.WriteToServerAsync(Table);
myConnection.Close();
}
catch (Exception (e))
{
console.write(e); …Run Code Online (Sandbox Code Playgroud) sqlbulkcopy ×10
c# ×6
sql-server ×4
sql ×3
asynchronous ×2
datatable ×2
asp.net ×1
async-await ×1
bitwise-or ×1
celery ×1
database ×1
f# ×1
matrix ×1
nullable ×1
oledb ×1
psycopg2 ×1
python ×1
vb.net ×1