Questo è il flusso di esecuzione del mio stored procedure
:L'inserimento non riesce nella transazione, ma SQL Server restituisce 1 riga/e interessata?
ALTER procedure dbo.usp_DoSomething
as
declare @Var1 int
declare @Var2 int
declare @Var3 int
select
@Var1 = Var1,
@Var2 = Var2,
@Var3 = Var3
from Table
where
...
BEGIN TRY
BEGIN TRANSACTION
/* UPDATE Table. This executes successfully */
/* INSERT Table. This fails due to PK violation */
COMMIT TRAN /* This does not happen */
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRAN /* This occurs because TRANS failed */
END CATCH
I UPDATE
viene eseguito correttamente. INSERT
non riesce, quindi viene eseguito il rollback dello transaction
.
Dopo l'esecuzione, la tabella sembra corretta e nulla è cambiato. Ma quando ho eseguito la SP, ottengo i seguenti messaggi:
(1 row(s) affected)
(0 row(s) affected)
Quindi mi chiedo, dove si trova il primo 1 row(s) affected
provenienti da?
Poi mi viene da pensare che questa è la ragione, ma ha voluto confermare: OUTPUT Clause (Transact-SQL)
An UPDATE, INSERT, or DELETE statement that has an OUTPUT clause will return
rows to the client even if the statement encounters errors and is rolled back.
The result should not be used if any error occurs when you run the statement.
sì, è tutto. – Quassnoi
Ma perché non segnalare l'errore per l''INSERTO'? Invece dice '0 row (s) affected'. È una sorta di fuorviante. – rbhat
Qui c'è un anti-pattern che chiamo try-squelch. Ti sei preso la briga di prendere un'eccezione, ma poi continui come se nulla fosse accaduto. Questo tipo di cose è incredibilmente difficile da eseguire il debug. Il rollback va bene, ma è necessario rilanciare l'eccezione in modo da sapere che succede e avere un'idea di cosa sia successo. –