Es scheint, dass der Rückgabewert ExecuteNonQuery
von einem Rollback nicht betroffen ist, obwohl die Dokumentation eindeutig angibt, dass dies der Fall ist. Hier sind einige mögliche Problemumgehungen.
1) Verwenden 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) Mit einem Rücklauf/Ausgabeparameter
SP: DECLARE @RowCount INT ERKLÄREN @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) Bewegen Sie den Rollback/Commit-Logik in den Code
Thi Mit s können Sie feststellen, ob ein Rollback aufgetreten ist, und bei Bedarf einen Wert von -1 ausgeben. Die Transaktionsanweisung müsste aus dem Sproc entfernt werden.
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();
}
}
}
Wie bereits erwähnt, die @@ ROWCOUNT-Wert und die ExecuteNonQuery Ergebnis werden beide von Trigger betroffen.
Was ist der Wert von res? – Peter
@peer in diesem Fall würde es 2. Die Anzahl der betroffenen Zeilen – coffeeyesplease
Interessanterweise wenn Sie nur diesen Code in SSMS ausführen, erhalten Sie "1 Zeile (n) betroffen" oder ähnlich. (Oder 2, oder was auch immer - aber nicht 0, obwohl es zurückgerollt wird.) – Rawling