在单个事务中发送多个SQL命令
本文关键字:SQL 命令 单个 事务 | 更新日期: 2023-09-27 18:17:29
我有一个巨大的INSERT INTO ...
字符串列表。目前我使用以下命令运行它们:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
foreach (var commandString in sqlCommandList)
{
SqlCommand command = new SqlCommand(commandString, connection);
command.ExecuteNonQuery();
}
}
我看到每个ExecuteNonQuery()
也执行commit。
- 是否有一种方法可以在单个事务中插入所有行(最后提交)?
- 我想要单个事务的原因是使我的"插入"过程更快。单笔交易是否也会让它更快?
如果你在一个线程中执行多个查询,建议使用SQL事务,你可以这样做:
SqlTransaction trans;
try
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
trans = connection.BeginTransaction();
foreach (var commandString in sqlCommandList)
{
SqlCommand command = new SqlCommand(commandString, connection,trans);
command.ExecuteNonQuery();
}
trans.Commit();
}
catch (Exception ex) //error occurred
{
trans.Rollback();
//Handel error
}
仅使用一个事务和命令可能会获得一些性能,如下所示:
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
connection.Open();
using (SqlTransaction trans = connection.BeginTransaction())
{
using (SqlCommand command = new SqlCommand("", connection,trans))
{
command.CommandType = System.Data.CommandType.Text;
foreach (var commandString in sqlCommandList)
{
command.CommandText = commandString;
command.ExecuteNonQuery();
}
}
trans.Commit();
}
}
catch (Exception ex) //error occurred
{
//Handel error
}
}
有点晚了,但是如果您要将所有值插入到同一个表中,则将SQL插入编码为"insert into tablex (f1, f2, f3,…)values (@F1,@F2,@F3…)"。创建命令并添加参数@F1…,然后在命令上设置Prepare标志。现在,在循环遍历要插入的值列表时,可以将它们设置为适当的参数,然后执行ExecuteNonQuery。SQL将预先解析命令字符串一次,然后每次都使用新参数。这样比较快。
最后,如果必须执行整个字符串,则可以通过在每个语句后面附加';'来在单个命令中执行多个SQL语句。您可以将这些命令串在一起,并向SQL server发出一个请求来执行它们。
您可以直接连接sql并让服务器处理它:
using (SqlConnection connection = new SqlConnection(connectionString))
{
string lsSql = string.Empty;
foreach (var commandString in sqlCommandList)
{
lsSql = lsSql + commandString + " ; " + Environment.NewLine;
}
connection.Open();
SqlCommand command = new SqlCommand(lsSql, connection);
command.ExecuteNonQuery();
}
这是我在日常工作中使用的,在使用foreach之前,我需要在数据库上运行任何非查询。你可以看到我正在使用OracleCommand,但如果你需要,你可以更改为SQL语句
public static void ExecuteDatabaseNonQuery(string command)
{
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
OracleTransaction transaction;
transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
cmd.Transaction = transaction;
try
{
cmd.CommandText = command;
var update = cmd.ExecuteNonQuery();
transaction.Commit();
Console.WriteLine("{0} rows updated", update);
}
catch (Exception e)
{
transaction.Rollback();
throw new Exception("Error: " + e);
}
}
注意:如果数据库中有未提交的更改,此方法将无限期等待
每个
可以使用Parallel using (SqlConnection connection = new SqlConnection(connectionString))
{
List<string> sqlCommandList = new List<string>();
connection.Open();
Parallel.ForEach(sqlCommandList, commandString =>
{
SqlCommand command = new SqlCommand(commandString, connection);
command.ExecuteNonQuery();
});
}