gpt4 book ai didi

c# - 回滚后ExecuteNonQuery的返回值

转载 作者:可可西里 更新时间:2023-11-01 03:02:29 24 4
gpt4 key购买 nike

假设我们有一个像这样的存储过程:

BEGIN TRANSACTION
UPDATE sometable SET aField = 0 WHERE anotherField = 1;
UPDATE sometable SET aField = 1 WHERE anotherField = 2;
ROLLBACK TRANSACTION;

从 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();
}

为什么我没有得到 res == -1?我仍然得到受影响的行数。当文档说明 "If a rollback occurs, the return value is also -1"

我在这里缺少什么?

最佳答案

看起来 ExecuteNonQuery 的返回值不受回滚的影响,尽管文档明确说明了这一点。以下是一些可能的解决方法。

1) 使用 ExecuteScalar

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

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();
}
}

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

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;
}
}

3) 将回滚/提交逻辑移动到代码中

这将使您能够确定是否发生回滚并在必要时输出值 -1。事务语句需要从存储过程中删除。

SP:

UPDATE Table1 SET Value1 = NULL

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();
}
}
}

如前所述,@@ROWCOUNT 值和 ExecuteNonQuery 结果均受触发器影响。

关于c# - 回滚后ExecuteNonQuery的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15070579/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com