que net ejemplos c# .net stored-procedures sqlclient

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í?