Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
DB Engine
SQL ServerMSDESQL Server CE
Services
Analysis (Data Mining)Analysis (OLAP)DTSIntegration ServicesNotification ServicesReporting Services
Programming
CLRConnectivitySQLXML
Other Technologies
ClusteringEnglish QueryFull-Text SearchReplicationService Broker
General
Data WarehousingPerformanceSecuritySetupSQL Server ToolsOther SQL Server Topics
DirectoryUser Groups
Related Topics
MS AccessOther DB ProductsMS Server Products.NET DevelopmentVB DevelopmentJava DevelopmentMore Topics ...

SQL Server Forum / General / Security / May 2007

Tip: Looking for answers? Try searching our database.

SQL 2000 Stored Procedure Problem

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Richard - 24 May 2007 16:10 GMT
Yesterday I spent hours searching the groups for a solution to this problem with no luck.

The issue is that a VB6 app I inherited has been running fine for years on SERVER1 (Server 2003 and SQL Server 2000).  We moved the Database to a new SERVER2 (Server 2003 and SQL Server 2000) .  The app has a mix of pass through SQL statements and I was in the process of converting them all to Stored Procedures.  Five of the 14 routines have been converted to Stored Procedures. On SERVER1 all work fine.

On SERVER2 only the pass through routines work.  Any that use Stored Procedures failed.  I then wrote a simple Stored Procedure that returned just a text string - that worked - so it is not just a Stored Procedure problem .  But as soon as I added a temp table to that "simple" Stored Procedure - it fails to return anything.  All 5 of the production routines that fail use Temp tables.

I have tried every combination of permissions settings I could find and nothing seemed to work.

Anyone have any ideas here ?

Thanks!!
Russell Fields - 24 May 2007 18:15 GMT
Richard,

Are you getting any error messages?  And, if so, what do they say?

Things to think about: Are all objects in the dbo schema?  On both servers?
Are there different rights granted on the two servers? (By temp tables, I do
understand you to mean #tables in tempdb.)

Since it works on one server not another, I would not expect execution
context to be the problem with temp tables.

Not much help, but any extra information you have could assist.
RLF

Yesterday I spent hours searching the groups for a solution to this problem
with no luck.

The issue is that a VB6 app I inherited has been running fine for years on
SERVER1 (Server 2003 and SQL Server 2000).  We moved the Database to a new
SERVER2 (Server 2003 and SQL Server 2000) .  The app has a mix of pass
through SQL statements and I was in the process of converting them all to
Stored Procedures.  Five of the 14 routines have been converted to Stored
Procedures. On SERVER1 all work fine.

On SERVER2 only the pass through routines work.  Any that use Stored
Procedures failed.  I then wrote a simple Stored Procedure that returned
just a text string - that worked - so it is not just a Stored Procedure
problem .  But as soon as I added a temp table to that "simple" Stored
Procedure - it fails to return anything.  All 5 of the production routines
that fail use Temp tables.

I have tried every combination of permissions settings I could find and
nothing seemed to work.

Anyone have any ideas here ?

Thanks!!
Richard - 24 May 2007 20:11 GMT
Thanks Russell

No error messages.  In VB6 / ADO - the recordset is just empty.  Failed to
mention that all work fine in QA and on my dev system, that's why I suspect
permissions.  BUT who, which and where ?? I swear - I tried so many things
yesterday.  GRANTs,  permissions on SProcs, permissions on DB, permissions
on tables - nothing helped.  The VB/ADO code that is SQL Pass Through (works
everywhere) uses the same UserID/password to login to the SQL as the SProc
routines.

All objects are in dbo. Both servers are "supposed" to be near identical -
the new one is a Quad CPU with bigger HDs.  I'm a programmer not an IT
expert by any means.  These permissions issues drive me up a wall.  I
insisted the migration go one thing at a time to minimize problems - good
thing!

I zeroed it down to the Temp tables with a simple test of 2 SProcs:

--- SProc 1
CREATE PROCEDURE spTestSimple AS
SELECT 'Test Simple' AS ReturnValue
------- This works everywhere 100%

--- SProc 2
CREATE PROCEDURE spTestTempTable AS
CREATE TABLE #MyTempTable
(
   ReturnValue varchar(100)
)
INSERT #MyTempTable
SELECT 'Test Temp Table'

SELECT  ReturnValue FROM #MyTempTable
-----  This works everywhere EXCEPT on the New Server from the VB/ADO app.

Any ideas?  My last resort is to undo all the SProcs back to the slow
inefficient Pass Through method. Yuk!

> Richard,
>
[quoted text clipped - 33 lines]
>
> Thanks!!
Erland Sommarskog - 24 May 2007 23:08 GMT
> --- SProc 2
> CREATE PROCEDURE spTestTempTable AS
[quoted text clipped - 10 lines]
> Any ideas?  My last resort is to undo all the SProcs back to the slow
> inefficient Pass Through method. Yuk!

Do you loop over .NextRecordset? Or do you set SET NOCOUNT ON
when you connect? If you do neither, I think we are on to something.
Try adding SET NOCOUNT ON in the beginning of the procedure.

As for why it works on one server, but not another, what does

sp_configure 'user options'

report on the two machines?

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 - 25 May 2007 00:49 GMT
Thanks Erland,

sp_configure 'user options'  reports the same on both :
minimum=0, Maximum=32767, config_value=0, run_value=0

I added SET NOCOUNT ON  as the first line in spTestTempTable - same results.
I had tried that yesterday while searching the groups for ideas for 5 hours.

Any other suggestions are welcome.

>> --- SProc 2
>> CREATE PROCEDURE spTestTempTable AS
[quoted text clipped - 21 lines]
>
> report on the two machines?
Erland Sommarskog - 25 May 2007 08:30 GMT
> sp_configure 'user options'  reports the same on both :
> minimum=0, Maximum=32767, config_value=0, run_value=0
[quoted text clipped - 4 lines]
>
> Any other suggestions are welcome.

What does your VB code looks like?

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

Russell Fields - 25 May 2007 14:28 GMT
Richard,

I am certainly confused.  There should be no rights issues that prevent you
from using a #temp table.

Could you check to make sure that you do not have a copy of your stored
procedure on master?  (I know that it is unlikely, but the behavior sounds
like you are not executing the code that you think you should be executing.)

RLF

> Thanks Erland,
>
[quoted text clipped - 32 lines]
>>
>> report on the two machines?
Richard - 25 May 2007 16:45 GMT
Thanks again Russell and Erland,

99% of the time I can search google groups for any issue I have and rarely
do I need to actually post a question.  There is usually and answer to
everything I have needed.  I've got over 10 years with VB and SQL Server -
and this is the most baffling problem.

I'm ABSOLUTELY sure it's not in Master - I have a test database that I use
and as I indicated, I can copy the exact call the VB app makes into QA and
it works.  I always use full path commands to ensure the right DB:

The VB code is identical in both cases except for the spTestTempTable vs.
spTestSimple :
Exec [999.23.17.99].[TestDatabase].[dbo].spTestTempTable

Exec [999.23.17.99].[TestDatabase].[dbo].spTestSimple

Also - this app has been running about 4 years on the old server - it still
does - we have 5 different companies using it and 3 are still on the old
server.   I am tasked with converting the VB6 apps to .NET - and the first
task was to get rid of the SQL pass through code into Stored Procs.  I
converted the 5 most intense ones over the past year - no problem.  Code got
smaller and reports got faster!

At first I suspected Stored Procedures in general - but I wrote the 2 simple
ones (see prev post) to prove that assumption wrong - the SProc that just
returns a string (spTestSimple ) works 100% - but as soon as I added the
#MyTempTable (spTestTempTable)  it fails to return anything to the VB app -
but ONLY on the New server.

I backed up the TestDatabase on the New Server - copied to my dev PC -
restored the DB in my SQL Server - since I had created spTestTempTable on
the Live New Server I verified that this SProc was indeed now in
TestDatabase on my dev PC - It was - ran the VB app - Works!

Conclusion :  Something on the New Server prevents a successful query from
VB6/ADO to a SQL Stored Procedure when that Stored Procedure uses a Temp
Table.

Again thanks guys for your input.
Richard

> Richard,
>
[quoted text clipped - 44 lines]
>>>
>>> report on the two machines?
Richard - 26 May 2007 18:20 GMT
Erland

Coincidently - I searched google for "SQL Stored Procedure Errors" and found
a GREAT tutorial on the subject.  Happens that it is your (Erland) site !
http://www.sommarskog.se/error-handling-II.html

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 errors
to see what happened.  The "Force Error" block works as expected when it is
before the "INSERT" - but when it's after the INSERT the app does not get
the error message and the recordset fails to OPEN. If I move the "-- BLOCK:
Trap Error"  Just After the INSERT - No error message is returned to the
app.

'---- The Test SProc:
SET NOCOUNT ON
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO

CREATE PROCEDURE spTestSproc11  AS

CREATE TABLE #MyTempTable
(
FinalReturnValue varchar(100)
)

DECLARE @err int
DECLARE @forceError int

INSERT INTO #MyTempTable (FinalReturnValue) VALUES ('spTestSproc11 with Temp
table')

-- BLOCK:  Force Error to see where this fails.
--   If this block is above the INSERT the client app gets it
--   If After the INSERT client does NOT see it
SELECT @forceError = 0
IF @forceError = 0
  BEGIN
     RAISERROR ('Forced Error ', 16, 1)
     RETURN 50000
  END
-- END BLOCK

-- BLOCK: Trap Error
SELECT @err = @@error
IF @err <> 0
 BEGIN
     RAISERROR ('INSERT Error ', 16, 1)
     --RETURN @err
RETURN 50001
  END
-- END BLOCK

SELECT  FinalReturnValue FROM #MyTempTable
SELECT @err = @@error
IF @err <> 0
 BEGIN
     RAISERROR ('SELECT Error ', 16, 1)
     --RETURN @err
RETURN 50002
  END

DROP TABLE #MyTempTable

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

---------------------------------------------------
Here is the VB Code:  - Note: This works on 3 dev PCs , the OldServer (SQL
2000 SP3) and ONLY Fails on NewServer (SQL 2000 SP4)
The recordset remains State= Closed  after the OPEN statement.

Private Sub cmdDevtest_Click(Index As Integer)
'--  Test  some simple SPROCs
   On Error GoTo Handler

   Dim sSql As String
   Dim objRsDetails    As ADODB.Recordset
   Dim objConn         As ADODB.Connection
   Dim tracer As String

   Set objConn = New ADODB.Connection
   objConn.Open CONNECTION_STRING, "", ""
   Set objRsDetails = New ADODB.Recordset

   If TextSpName.Text <> "" Then
       sSql = " exec " & IpDatabaseOwner & TextSpName.Text
   Else
       If Index = 0 Then
          sSql = " exec " & IpDatabaseOwner & "spTestSprocSimple "
       Else
          sSql = " exec " & IpDatabaseOwner & "spTestTempTable "
       End If
   End If

   tracer = "1"
   objRsDetails.Open sSql, objConn

   tracer = "2 RS State = " & objRsDetails.State
   If Not (objRsDetails.EOF Or objRsDetails.BOF) Then
       tracer = "3"
       objRsDetails.MoveFirst
   End If

   tracer = "4"
   frmMain.txtPreview.Text = Now() & "  " & objRsDetails.Fields(0).Value

ExitMe:
   On Error Resume Next
   objRsDetails.Close
   Set objRsDetails = Nothing
   objConn.Close
   Set objConn = Nothing
   Exit Sub

Handler:
   MsgBox "ERROR: " & Err.Description & vbCrLf & "SQL = " & sSql & vbCrLf &
" OConn = " & objConn & vbCrLf & " Tracer = " & tracer
   Resume ExitMe
End Sub
Erland Sommarskog - 26 May 2007 20:24 GMT
> 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

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.