File this one away for the next time you code review a SQL Server stored procedure. Those OUTPUT parameters aren’t bound to your transactions in any way.
Observe:
Create proc sp_OutputMyIdent (@myOutputIdent int output)
as
set nocount on
Begin transaction
Insert myIdentTable Select 'foo'
Select @myOutputIdent = @@Identity
rollback transaction
go
Now a little ADO from JScript:
myCommand.CommandText = "sp_OutputMyIdent";
myCommand.CommandType = adCmdStoredProc;
myCommand.ActiveConnection = myConnection;
myCommand.Parameters("@myOutputIdent") = 0;
WScript.Echo("Before: " + myCommand.Parameters("@myOutputIdent"));
myCommand.Execute();
WScript.Echo("After: " + myCommand.Parameters("@myOutputIdent"));
Which yields the following:
Errors don’t alter this behavior at all. Any reasonably competent scripting programmer can trap and then disregard your error.
Observe:
Create proc sp_OutputMyIdent (@myOutputIdent int output)
as
set nocount on
Begin transaction
Insert myIdentTable Select 'foo'
Select @myLocalVar = @@Identity
RaisError ( N'Uh Oh!', 16, 1 )
rollback transaction
go
try
{
myCommand.CommandText = "sp_OutputMyIdent";
myCommand.CommandType = adCmdStoredProc;
myCommand.ActiveConnection = myConnection;
myCommand.Parameters("@myOutputIdent") = 0;
WScript.Echo("Before: " + myCommand.Parameters("@myOutputIdent"));
myCommand.Execute();
}
catch(e){ WScript.Echo(e.description) }
WScript.Echo("After: " + myCommand.Parameters("@myOutputIdent"));
Which yields the following:
Before: 0
Uh Oh!
After: 2
The best thing to do is to keep your progress private until you know you are done:
Create proc sp_OutputMyIdent (@myOutputIdent int output)
as
set nocount on
Declare @myLocalVar int
Begin transaction
Insert myIdentTable Select 'foo'
Select @myLocalVar = @@Identity
RaisError ( N'Uh Oh!', 16, 1 )
commit transaction
Select @myOutputIdent = @myLocalVar
go