c# - net - Valor de retorno de ExecuteNonQuery después de la reversión
que es executescalar c# (1)
Parece que el valor de retorno de ExecuteNonQuery
no se ve afectado por una reversión aunque la documentación ExecuteNonQuery
claramente que sí lo hace. Aquí hay algunas soluciones posibles.
1) Utilice 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
DO#
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) Utilice un parámetro de retorno / salida
SP: DECLARAR @RowCount INT DECLARAR @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
DO#
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) Mueva la lógica rollback / commit al código
Esto le daría la posibilidad de determinar si se produjo una reversión y generar un valor de -1 cuando sea necesario. La declaración de la transacción tendría que eliminarse del sproc.
SP:
UPDATE Table1 SET Value1 = NULL
DO#:
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();
}
}
}
Como se señaló anteriormente, el valor @@ ROWCOUNT y el resultado de ExecuteNonQuery se ven afectados por los desencadenantes.
Suponiendo que tenemos un procedimiento almacenado que hace algo como esto:
BEGIN TRANSACTION
UPDATE sometable SET aField = 0 WHERE anotherField = 1;
UPDATE sometable SET aField = 1 WHERE anotherField = 2;
ROLLBACK TRANSACTION;
Y desde C # tenemos algo como esto:
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();
}
¿Por qué no estoy recibiendo res == -1? Todavía estoy recibiendo el número de filas afectadas. Cuando la documentación indica "Si se produce una reversión, el valor de retorno también es -1"
¿Qué me estoy perdiendo aquí?