zorvek (Kevin Jones)
asked on
Return Warning from SQL Server to VBA via ADODB Connection
I am trying to generate a warning in a SQL Server store procedure that is returned to VBA via an ADODB connection. If I use RAISEERROR with a severity of 11 or higher, the error is returned to VBA but the stored procedure aborts. If I use a severity of 10 or lower, the stored procedure does not abort but the "error" is not returned to the VBA caller.
How can I generate an "error" that is returned to the caller via the ADODB connection object without forcing the stored procedure to abort?
Kevin
How can I generate an "error" that is returned to the caller via the ADODB connection object without forcing the stored procedure to abort?
Kevin
ASKER
I tried that but they are not included in the errors collection unless a fatal error occurs.
Kevin
Kevin
And are the .NET alternatives totally out of the question? I've found it easier to achieve in .NET (though I sometimes hadd issues with the PRINT buffering messages and giving them in one big block at the end). Other than that, umm.. my ADODB is now really rusty :)
ASKER
I'm using VBA in Excel.
ASKER
I'm currently trying to use the XACT_ABORT switch but that doesn't seem to stop the stored procedure from aborting:
SET XACT_ABORT OFF
RAISERROR ('Warning message', 11, 1)
SET XACT_ABORT ON
Kevin
SET XACT_ABORT OFF
RAISERROR ('Warning message', 11, 1)
SET XACT_ABORT ON
Kevin
What happens if you put the RAISEERROR in TRY..CATCH blocks? Does the Error still get passed to the application?
Also, is this how you are processing your error messages on the VBA side (from the MS website link I gave you earlier):
Also, is this how you are processing your error messages on the VBA side (from the MS website link I gave you earlier):
Do While (Not ADORs Is Nothing)
If ADORs.State = adStateClosed Then Exit Do
While Not ADORs.EOF
For i = 0 To ADORs.Fields.Count - 1
rStr = rStr & " : " & ADORs(i)
Next i
Debug.Print Mid(rStr, 3, Len(rStr))
ADORs.MoveNext
rStr = ""
Wend
Debug.Print "----------------------"
Set ADORs = ADORs.NextRecordset
Loop
If attempting to use this to process PRINT and RAISEERROR messages does not yield results, what if we try to issue example SELECT "This has happened" AS Message and treating this as a stored procedure that just returns multiple result sets? So long as the ADORs.State <> adStateClosed... can we not keep consuming the results like that?
ASKER
They are in the CATCH part of a TRY..CATCH block.
ASKER
Actually, the SP does continue executing, but the recordsets are not being returned. When I run the query in SSMS everything works as desired: I get the warnings/errors AND the recordset. But the recordset is not returned the caller when called from VBA using ADODB.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
You've always the option to use MARS (Multiple Active Result Sets) - the first result set is the usual one, the second a status info.
ASKER
We considered that. We also considered return parameters. The problem is that we have a toolkit already built and in use by hundreds of applications and thousands of stored procedures. And many of those stored procedures are already designed to return multiple recordsets. The toolkit is coded to look at the Errors collection and take appropriate action.
The bottom line is we're kinda screwed on this one. Fortunately, we only have a select few instances where we need a warning versus an error with an aborted stored procedure so we are circumventing the deficiency with preflighting--implementing stored procedures to check for warning conditions outside of the stored procedures that actually do the work,
All that said, I'm still considering an Nth recordset in the event that a warning or other status information is needed to be sent back to the caller. The recordset schema would have to be unique so that it can be identified and pulled out of the normal set of data recordsets. Since a recordset can't be named, it would have to be identified by a unique set of field names that would never occur in normal operation.
Kevin
The bottom line is we're kinda screwed on this one. Fortunately, we only have a select few instances where we need a warning versus an error with an aborted stored procedure so we are circumventing the deficiency with preflighting--implementing
All that said, I'm still considering an Nth recordset in the event that a warning or other status information is needed to be sent back to the caller. The recordset schema would have to be unique so that it can be identified and pulled out of the normal set of data recordsets. Since a recordset can't be named, it would have to be identified by a unique set of field names that would never occur in normal operation.
Kevin
Agree, then you are stuck ATM. Adding a unqiue resultset still seems the best way to handle for the future, but of course requires to rewrite the toolkit, all as you said. "You can't do that" is indeed the short-term answer.
ASKER
ATM?
ASKER
The answer, as far as I can tell, is that the objective cannot be realized.
Open in new window
You'll probably be wanting to view the messages in real time though... so look here http://support.microsoft.com/kb/194792In ADO.NET it is event driven through the SqlInfoMessageEventHandler