> I made some mods to the failing SProc and zeroed in on INSERT statement.
> I used a few Blocks of code (from your tutorial) in the SProc to force
[quoted text clipped - 3 lines]
> move the "-- BLOCK: Trap Error" Just After the INSERT - No error
> message is returned to the app.
It is, but you have to look for it.
You can find it directly on objConn.Errors, or it will be raised when you
call .NextRecordset. And if you run with SET NOCOUNT ON (see also below),
it should appear directly. When NOCOUNT is off, the INSERT statement
generates a "rows affected" message, and the error is queued behind that
message.
But it is certainly quite confusing when ADO returns an error. The good
news is that if you are heading for SqlClient, is that ADO .Net is a lot
cleaner. Particularly if you use the connection property
.FireInfoMessageEventsOnUserErrors.
There are a few things that are not clear to me. You talk about running
on different servers. Do you always run the client application on the
same machine? Or you always run it on the SQL Server machine?
You stored-procedure calls appears to include a linked server. Is this
linked server always the one and the same? Or is the SQL Server you
connect to always the same, and then you call different linked servers?
Permit me a couple of more comments.
> '---- The Test SProc:
> SET NOCOUNT ON
> GO
Whether you have SET NOCOUNT ON when you create the procedure matters
little. This setting is not saved with the procedure, but the run-time
setting applies. You have better use for this statement inside the
procedure.
> SET QUOTED_IDENTIFIER OFF
> GO
> SET ANSI_NULLS OFF
> GO
Any particular reason that you have these in the non-standard position?
Or are you just victim of the crap known as Enterprise Manager? Keep in
mind that there are features in SQL Server that are not available when
these settings are OFF, so there is all reason to have them ON. (These
two settings *are* saved with the procedure, so this is where it matters.)
> Private Sub cmdDevtest_Click(Index As Integer)
> '-- Test some simple SPROCs
[quoted text clipped - 6 lines]
>
> Set objConn = New ADODB.Connection
You don't set the cursor location. I strongly recommend using client-
side cursors.
> objConn.Open CONNECTION_STRING, "", ""
> Set objRsDetails = New ADODB.Recordset
[quoted text clipped - 8 lines]
> End If
> End If
Rather than using adCmdText, use adCmdStoredProcedure. Then the stored
procedure is called trough RPC which is more effective. That also forces
you to use the parameters collection when you have parameters. And
that is a good thing. Never embed user values into the SQL string
directly.

Signature
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
Richard - 26 May 2007 23:21 GMT
Again, Many thanks Erland !
Please see my in line comments/answers to your questions. They are indicated
by ********
>> I made some mods to the failing SProc and zeroed in on INSERT statement.
>> I used a few Blocks of code (from your tutorial) in the SProc to force
[quoted text clipped - 11 lines]
> generates a "rows affected" message, and the error is queued behind that
> message.
******** The error trap in the VB app is raised on any reference to the
recordset (Operation is not allowed when object is closed).
objRsDetails.MoveFirst triggers it. "If objRsDetails.EOF" triggers it.
That's why I looked at objRsDetails.State after the Open - it = 0 (Closed) -
so the open fails! I also just now tested objConn.Errors.Count and it = 0.
So I'm really perplexed now since it appears I cannot even "look for it".
> But it is certainly quite confusing when ADO returns an error. The good
> news is that if you are heading for SqlClient, is that ADO .Net is a lot
> cleaner. Particularly if you use the connection property
> .FireInfoMessageEventsOnUserErrors.
******** Yes - There is a web site attached to this project that I already
converted 100% .Net / ADO.Net - and yes it's much cleaner all over.
> There are a few things that are not clear to me. You talk about running
> on different servers. Do you always run the client application on the
> same machine? Or you always run it on the SQL Server machine?
> You stored-procedure calls appears to include a linked server. Is this
> linked server always the one and the same? Or is the SQL Server you
> connect to always the same, and then you call different linked servers?
******** Server1 (older) does use linked servers since that's where the web
site resides and it has to read from either Server - it works fine.
Ultimately Server1 is going away - and the linked server will no longer be
needed. But this problem app does not use it - it is just a Reports App and
the server that has the app will always be the same server that has their
SQL Server and Database. The full "IP.DBName.[dbo]" is simply used to make
it easier to manage since the IP and DB are in a Setup Table that depending
on the customer the IP "may" be different and the DBName will always be
different.
This Reports app is run over a VPN - and there is another huge front end VB6
app that is the heart of all the data entry - it still has 100% SQL pass
through (also scheduled for .NET conversion) and it works fine on both
servers. Lucky the Reports app is the less critical one.
> Permit me a couple of more comments.
>
[quoted text clipped - 17 lines]
> these settings are OFF, so there is all reason to have them ON. (These
> two settings *are* saved with the procedure, so this is where it matters.)
******** Did not know there was a standard order. Must be Enterprise
Manager - I used its template.
>> Private Sub cmdDevtest_Click(Index As Integer)
>> '-- Test some simple SPROCs
[quoted text clipped - 9 lines]
> You don't set the cursor location. I strongly recommend using client-
> side cursors.
******** AH good notice ! The actual code DOES have the client-cursor - I
just removed it today from this
test routine to see if it had any affect - none ! Same results. I'm grasping
at straws at this point.
>> objConn.Open CONNECTION_STRING, "", ""
>> Set objRsDetails = New ADODB.Recordset
[quoted text clipped - 14 lines]
> that is a good thing. Never embed user values into the SQL string
> directly.
*****************************
**** I agree - I am simply trying to get the VB6 app trimmed down (Stored
Procedures etc) so the conversion to .NET will be easier - where I will
implement the ADO.NET correctly with the SProc methods.
*****************************
!!! One last thing: I just changed the SProc to INSERT to one of the
Existing data tables in the DB - Not a temp one !! It WORKS ! So it's not a
permissions on the INSERT command itself - just when INSERT to a Temp Table
!
Baffling !!
AlexS - 27 May 2007 03:39 GMT
Do you have enough space available for tempdb?
Any errors in server log - when insert is eaten up?
> Again, Many thanks Erland !
>
[quoted text clipped - 132 lines]
> Table !
> Baffling !!
Richard - 27 May 2007 04:54 GMT
Thanks Alex,
Brand new server with "terra bytes" of storage - there is no Temp DB just a
Temp Table. No errors in the log.
Thanks for grabbing at a few straws with me.
> Do you have enough space available for tempdb?
> Any errors in server log - when insert is eaten up?
[quoted text clipped - 140 lines]
>> Table !
>> Baffling !!
AlexS - 27 May 2007 05:01 GMT
Not sure how you don't have tempdb and have temp table -see this link
http://msdn2.microsoft.com/en-us/library/ms190768.aspx
> Thanks Alex,
>
[quoted text clipped - 151 lines]
>>> Temp Table !
>>> Baffling !!
Erland Sommarskog - 27 May 2007 10:02 GMT
> ******** The error trap in the VB app is raised on any reference to the
> recordset (Operation is not allowed when object is closed).
> objRsDetails.MoveFirst triggers it. "If objRsDetails.EOF" triggers it.
>
> That's why I looked at objRsDetails.State after the Open - it = 0 (Closed)
> - so the open fails!
No, that just means that the first recordset you get is a rowcount from
the INSERT. Use .NextRecordset to proceed to the next. Or issue SET
NOCOUNT ON in your procedure.
> ******** Server1 (older) does use linked servers since that's where the
> web site resides and it has to read from either Server - it works
[quoted text clipped - 5 lines]
> IP and DB are in a Setup Table that depending on the customer the IP
> "may" be different and the DBName will always be different.
So on the old server where things work, you connect to one server, and
then issue a call stored procedure on a second server through the first
server? But on the server you are having problems with, the IP address
is the same as the server you connect to, so that you have a loopback?
This could explain why it works on the first server: the rowcount is
consumed by the server you connect to, and does not reach your client.
Whereas in the second case SQL Server is smart enough to shortcut,
and there is not really any linked server, so it is a direct call to
the procedure.

Signature
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx