c# 在事务中检索插入的 ID
c# Retrieving Inserted ID inside Transaction
我有一堆插入,我想在事务中插入,这样我就可以在出现任何错误时回滚。现在我的问题是,对于某些插入,我需要前一个插入的 ID。但是,执行 var id = (int)command.ExecuteScalar();
会引发异常 ("Object reference not set to an instance of an object")。如果我 运行 command.ExecuteScalar()
没有尝试分配结果,代码工作得很好。是否可以在提交交易前获取 ID?如果不是,我有什么选择?
我的代码:
using (SqlConnection connection = new SqlConnection("ConnectionHere")
{
connection.Open();
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
// Start a local transaction.
transaction = connection.BeginTransaction();
command.Connection = connection;
command.Transaction = transaction;
try
{
string insertStudent = "INSERT INTO Students (FirstName, MiddleName, LastName)" +
" VALUES (@firstName, @middleName, @lastName)";
command.CommandText = insertStudent;
command.Parameters.AddWithValue("@firstName", application.FirstName);
command.Parameters.AddWithValue("@middleName", application.MiddleName);
command.Parameters.AddWithValue("@lastName", application.LastName);
var id = (int) command.ExecuteScalar();//EXCEPTION THROWN HERE
// Attempt to commit the transaction.
transaction.Commit();
}
catch (Exception ex)
{
Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
// Attempt to roll back the transaction.
transaction.Rollback();
}
}
使用此 SQL 语法获取插入的 ID:
INSERT INTO Students (FirstName, MiddleName, LastName) OUTPUT Inserted.ID ....
然后
int id = command.ExecuteScalar();
我假设 Students table 中的一列设置为标识列,并且您使用 SQL Server 2008+。
在这种情况下,您需要将 SQL 语句更改为 return 插入的标识值,如下所示:
string insertStudent = "INSERT INTO Students (FirstName, MiddleName, LastName)" +
" VALUES (@firstName, @middleName, @lastName);" +
" SELECT SCOPE_IDENTITY();";
有关 SCOPE_IDENTITY 的更多信息可在此处找到:https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql
只需更改代码
var id = (int) command.ExecuteScalar();
如:
int id = Convert.ToInt32(cmd.ExecuteScalar());
这将确保即使 ExecuteScalar returns 为 null,由于未在存储过程中选择任何内容,countDis 的值为 0。因为 Convert.ToInt32(null) = 0.
我有一堆插入,我想在事务中插入,这样我就可以在出现任何错误时回滚。现在我的问题是,对于某些插入,我需要前一个插入的 ID。但是,执行 var id = (int)command.ExecuteScalar();
会引发异常 ("Object reference not set to an instance of an object")。如果我 运行 command.ExecuteScalar()
没有尝试分配结果,代码工作得很好。是否可以在提交交易前获取 ID?如果不是,我有什么选择?
我的代码:
using (SqlConnection connection = new SqlConnection("ConnectionHere")
{
connection.Open();
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
// Start a local transaction.
transaction = connection.BeginTransaction();
command.Connection = connection;
command.Transaction = transaction;
try
{
string insertStudent = "INSERT INTO Students (FirstName, MiddleName, LastName)" +
" VALUES (@firstName, @middleName, @lastName)";
command.CommandText = insertStudent;
command.Parameters.AddWithValue("@firstName", application.FirstName);
command.Parameters.AddWithValue("@middleName", application.MiddleName);
command.Parameters.AddWithValue("@lastName", application.LastName);
var id = (int) command.ExecuteScalar();//EXCEPTION THROWN HERE
// Attempt to commit the transaction.
transaction.Commit();
}
catch (Exception ex)
{
Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
// Attempt to roll back the transaction.
transaction.Rollback();
}
}
使用此 SQL 语法获取插入的 ID:
INSERT INTO Students (FirstName, MiddleName, LastName) OUTPUT Inserted.ID ....
然后
int id = command.ExecuteScalar();
我假设 Students table 中的一列设置为标识列,并且您使用 SQL Server 2008+。
在这种情况下,您需要将 SQL 语句更改为 return 插入的标识值,如下所示:
string insertStudent = "INSERT INTO Students (FirstName, MiddleName, LastName)" +
" VALUES (@firstName, @middleName, @lastName);" +
" SELECT SCOPE_IDENTITY();";
有关 SCOPE_IDENTITY 的更多信息可在此处找到:https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql
只需更改代码
var id = (int) command.ExecuteScalar();
如:
int id = Convert.ToInt32(cmd.ExecuteScalar());
这将确保即使 ExecuteScalar returns 为 null,由于未在存储过程中选择任何内容,countDis 的值为 0。因为 Convert.ToInt32(null) = 0.