cof*_*ase 17 .net c# stored-procedures sqlclient
假设我们有一个存储过程就像这样:
BEGIN TRANSACTION
UPDATE sometable SET aField = 0 WHERE anotherField = 1;
UPDATE sometable SET aField = 1 WHERE anotherField = 2;
ROLLBACK TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
从C#我们有这样的事情:
using (var connection = new SqlConnection("connection string"))
{
connection.Open();
var cmd = connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "my_procedure";
var res = cmd.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)
为什么我没有得到res == -1?我仍然得到受影响的行数.当文档声明"如果发生回滚,返回值也为-1"
我在这里缺少什么?
看起来 的返回值ExecuteNonQuery不受回滚的影响,尽管文档明确指出会受到回滚的影响。以下是一些可能的解决方法。
1) 使用执行标量
SP:
DECLARE @RowCount INT
DECLARE @Error INT
BEGIN TRAN
UPDATE Table1 SET Value1 = NULL
SELECT @RowCount = @@ROWCOUNT, @Error = @@ERROR
IF @Error <> 0 BEGIN
ROLLBACK TRAN
SELECT -1
END ELSE BEGIN
COMMIT TRAN
SELECT @RowCount
END
Run Code Online (Sandbox Code Playgroud)
C#
using (SqlConnection dbConnection = new SqlConnection("Data Source=.;Initial Catalog=Database1;Integrated Security=True;MultipleActiveResultSets=True"))
{
dbConnection.Open();
using (SqlCommand command = dbConnection.CreateCommand())
{
command.CommandText = "QuickTest";
command.CommandType = CommandType.StoredProcedure;
rowsAffected = command.ExecuteScalar();
}
}
Run Code Online (Sandbox Code Playgroud)
2) 使用返回/输出参数
SP: 声明@RowCount INT 声明@Error INT
BEGIN TRAN
UPDATE Table1 SET Value1 = NULL
SELECT @RowCount = @@ROWCOUNT, @Error = @@ERROR
IF @Error <> 0 BEGIN
ROLLBACK TRAN
RETURN -1
END ELSE BEGIN
COMMIT TRAN
RETURN @RowCount
END
Run Code Online (Sandbox Code Playgroud)
C#
using (SqlConnection dbConnection = new SqlConnection("Data Source=.;Initial Catalog=Database1;Integrated Security=True;MultipleActiveResultSets=True"))
{
dbConnection.Open();
using (SqlCommand command = dbConnection.CreateCommand())
{
command.Parameters.Add(new SqlParameter() {Direction = ParameterDirection.ReturnValue });
command.CommandText = "QuickTest";
command.CommandType = CommandType.StoredProcedure;
command.ExecuteNonQuery();
rowsAffected = command.Parameters[0].Value;
}
}
Run Code Online (Sandbox Code Playgroud)
3)将回滚/提交逻辑移至代码中
这将使您能够确定是否发生回滚并在必要时输出值 -1。事务语句需要从存储过程中删除。
SP:
UPDATE Table1 SET Value1 = NULL
Run Code Online (Sandbox Code Playgroud)
C#:
using (SqlConnection dbConnection = new SqlConnection("Data Source=.;Initial Catalog=Database1;Integrated Security=True;MultipleActiveResultSets=True"))
{
dbConnection.Open();
using (SqlTransaction tran = dbConnection.BeginTransaction())
{
using (SqlCommand command = dbConnection.CreateCommand())
{
command.Transaction = tran;
try
{
command.Parameters.Add(new SqlParameter() {Direction = ParameterDirection.ReturnValue });
command.CommandText = "QuickTest";
command.CommandType = CommandType.StoredProcedure;
rowsAffected = command.ExecuteNonQuery();
}
catch (Exception)
{
rowsAffected = -1;
throw;
}
tran.Commit();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如前所述,@@ROWCOUNT 值和 ExecuteNonQuery 结果均受触发器影响。