Link to home
Start Free TrialLog in
Avatar of Member_2_1767690
Member_2_1767690

asked on

In classic ADO / SQLOLEDB provider, can a successful update return a non-zero error number?

When our legacy application executes an UPDATE statement, our code behaves as if an exception has been raised (and assumes the update has not worked), yet the effects of the update have been found later to be committed to the database.

Due to the infrequency of the issue, we are unable to obtain any exact error numbers or descriptions - we only know the issue is occurring due to the resultant effects on the database tables.

Is it even possible to get non-zero errors from ADO / SQL OLEDB provider when the UPDATE actually succeeds??

Please Note: This is a legacy VB6 app, Classic ADO with SQL OLEDB provider - nothing to do with dot NET.
SOLUTION
Avatar of James Elliott
James Elliott
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Member_2_1767690
Member_2_1767690

ASKER

Hi, James and jkaios.

Thank you both for your input.

Yes, we are aware of the SET NOCOUNT ON issue - in this case, we believe the statement is failing with a non-zero error, before we are able to check the RecordsAffected property. The code assumes the statement has failed if a non-zero error is raised and therefore does not bother to check RecordsAffected - only if the statement succeeds with no error do we check RecordsAffected.

I guess my question could be re-worded as: "Would it be possible for RecordsAffected (once populated) to be > 0 if Err.Number was <> 0"?

Also, in VB6 we cannot use the (dot Net only) SQLDataReader or SQLDataAdapter - we're just using the ADO command object itself.

Also, yes, we already do use OnError - we use it to capture the error number, description and procedural context to a trace file, however due to client request, we cannot enable the tracing permanently to capture it and inspect it accordingly (as the trace files end up being huge). We only know the error trap is firing, because of what the caller method is doing next in the database.

Thanks anyway, guys - much appreciated ;-)
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If something went wrong on line 6, the compiler will automatically trigger line 14, which displays the error in a message box.  But if line 6 succeeds, then any code following it, such as lines 8 - 12 will run.
Thanks, jkaios.

Yes, the Records Affected parameter is what I meant - I was trying to split the terms I was using between classic VB and dot NET which James was using.

No matter - I will close the question - I'm not after how to capture the error - we already have error traps like the ones you describe, but are restricted in the tracing and messaging options available to us to read or log any error that is raised in these traps - its a production system (no message boxes allowed, no trace files allowed). My question does not require me to know what the error is - just whether an update statement can succeed IF ADO does raise an error number <> 0 (i.e. anything, it doesn't matter what number - any error at all).

In your example - let's say the error trap fires and the message box is raised. Under any circumstance then, is it possible for say, the UPDATE statement to actually write the value somevalue to the field somefield in the database - i.e. perhaps a non-critical error or warning raised as an error? Our code currently assumes if it enters the error trap, the statement has failed and no value has been written to the database - I want to know if that assumption can be broken.
Point taken, thanks for the clarification.  BTW, that's a very good point!

One approach is to use "transaction processing", which ADO fully supports so that if ANYTHING (any kind of error) ever happens during an UPDATE or INSERT operation, simply "roll back" any changes that might have happened to your DB.  And the proper place to roll back any changes is in your error trap routine.

A second approach is to query the specific record that was supposed to be updated and check if it has the new result or not.

Hope this helps?

Example on lines 7, 11, and 20:

Sub updateName()

   On Error Goto Error_Trap:

   Dim NumOfRecsAff as Long

   ADO.BeginTrans        'intialize our Transaction Processing
   
   ADO.Execute "UPDATE sometable set somefield = 'some value'", NumOfRecsAff
   
   ADO.CommitTrans       'finalize any update, flush any pending writes to the DB

   If (NumOfRecsAff <> 0) Then
      msgbox "number of recs affected: " & NumOfRecsAff
   End If

   Exit Sub
Error_Trap:
   MsgBox Err.Description, vbCritical, "ADO Error# " & Err.Number
   ADO.RollbackTrans     'cancel anything that might have happened to our DB

End Sub

Open in new window

Thanks, jkaios.

Yes, thanks for the point on transactions - we have begin /commit /rollback at a higher level, so that we can atomically commit a number of records or not, rather than individual records at a time - the problem for us lies in what happens in between (there are intermediate repeat loops designed to get around transient lock/timeout problems).

I am contemplating forcing a transaction around each statement, but that gets into nested transactions, and this problem:

http://support2.microsoft.com/kb/177138/en-us

Mostly, I believe we get the error message as a result of attempting nested transactions. I cannot recall exactly, but I believe that in some scenarios the SQL OLEDB provider "fakes" nested transactions, by creating another database connection behind the scenes, which causes further problems with connection timeout properties - I will have to dig back through my notes on that issue.

Anyway - thanks so much for your help - it's good to have someone take the time to respond to questions!

Cheers.

Ed.
Always a pleasure to help n have a great weekend.