Problem calling stored procedure from another stored procedure via classic ASP - sql-server

We have a classic ASP application that simply works and we have been loathe to modify the code lest we invoke the wrath of some long-dead Greek gods.
We recently had the requirement to add a feature to an application. The feature implementation is really just a database operation requires minimal change to the UI.
I changed the UI and made the minor modification to submit a new data value to the sproc call (sproc1).
In sproc1 that is called directly from ASP, we added a new call to another sproc that happens to be located on another server, sproc2.
Somehow, this does not work via our ASP app, but works in SQL Management Studio.
Here's the technical details:
SQL 2005 on both database servers.
Sql Login is authenticating from the ASP application to SQL 2005 Server 1.
Linked server from Server 1 to Server 2 is working.
When executing sproc1 from SQL Management Studio - works fine. Even when credentialed as the same user our code uses (the application sql login).
sproc2 works when called independently of sproc1 from SQL Management Studio.
VBScript (ASP) captures an error which is emitted in the XML back to the client. Error number is 0, error description is blank. Both from the ADODB.Connection object and from whatever Err.Number/Err.Description yields in VBScript from the ASP side.
So without any errors, nor any reproducibility (i.e. through SQL Mgmt Studio) - does anyone know the issue?
Our current plan is to break down and dig into the code on the ASP side and make a completely separate call to Server 2.sproc2 directly from ASP rather than trying to piggy-back through sproc1.

Have you got set nocount on set in both stored procedures? I had a similar issue once and whilst I can't remember exactly how I solved it at the moment, I know that had something to do with it!

You could be suffering from the double-hop problem
The double-hop issue is when the ASP/X page tries to use resources that are located on a server that is different from the IIS server.
Windows NT Challenge/Response does not support double-hop impersonations (in that once passed to the IIS server, the same credentials cannot be passed to a back-end server for authentication).
You should verify the attempted second connection using SQL Profiler.
Note that with your manual testing you are not authenticating via IIS. It's only when you initiate the sql via the ASP/X page that this problem manifests.
More resources:
http://support.microsoft.com/kb/910449
http://support.microsoft.com/kb/891031
http://support.microsoft.com/kb/810572

I had a similar problem and I solved it by setting nocount on and removing print commands.

My first reaction is that this might not be an issue of calling cross-server, but one of calling a second proc from a first, and that this might be what's acting differently in the two different environments.
My first question is this: what happens if you remove the cross-server aspect from the equation? If you could set up a test system where your first proc calls your second proc, but the second proc is on the same server and/or in the same database, do you still get the same problem?
Along these same lines: In my experience, when the application and SSMS have gotten different results like that, it has often been an issue of the stored procedures' settings. It could be, as Luke says, NOCOUNT. I've had this sort of thing happen from extraneous PRINT statements in the code, although I seem to remember the PRINTed value becoming part of the error description (very counterintuitively).
If anything is returned in the Messages window when you run this in SSMS, find out where it is coming from and make it stop. I would have to look up the technical terms, but my recollection is that different querying environments have different sensitivities to "errors", and that a default connection via SSSM will not throw an error at certain times when an ADO connection from a scripting language will.
One final thought: in case it is an environment thing, try different settings on your ASP page's connection string. E.g., if you have an OLEDB connection, try ODBC. Try the native and non-native SQL Server drivers. Check out what connection string options your provider supports, and try any of them that seem like they might be worth trying.

Example code might help :) Are you trying to return two tables from the stored procedure; I don't think ADO 2.6 can handle multiple tables being returned.

I did consider that (double-hop), but what is the difference between a sproc-in-a-sproc call like I am referring to vs. a typical cross-server join via INNER JOIN? Both would be executed on Server1, using the Linked Server credentials, and authenticating to Server 2.
Can anyone confirm that calling a sproc cross-server is different than doing a join on data tables? And why?
If the Linked Server config is a sql account - is that considered a double-hop (since what you refer to is NTLM double-hops?)
In terms of whether multiple resultsets are coming back - no. Both Server1.Sproc1 and Server2.Sproc2 would be "ExecuteNonQuery()" in the .net world and return nothing (no resultsets and no return values).

Try to check the permissions to the database for the user specified in the connection string.
Use the same user name in the connection string to log in to the database while using sql mgmt studio.
create some temporary table to write the intermediate values and exceptions since it can be a effective way of debugging your application.

Can I just check: You made the addition of sproc2? Prior to that it was working fine for ages.
Could you not change where you call sproc2 from? Rather than calling it from inside sproc1, can you call it from the ASP? That way you control the authentication to SQL in the code, and don't have to rely on setting up any trusts or shared remote authentication on the servers.

How is your linked server set up? You generally have some options as to how it authenticates to the remote server, which include logging in as the currently logged in user or specifying a SQL login to always use. Have you tried setting it to always use a specific account? That should eliminate any possible permissions issues in calling the remote procedure...

Related

Can I debug a Stored Procedure in SQL Server Express Edition with Advanced Services?

Trying to debug a stored procedure on a local SQL Server Express instance. I am running SSMS As Administrator. My login is in the sysadmin server role. My connection user is in the sysadmin server role. I get the message "Unable to start the Transact-SQL debugger, could not connect to the Database Engine instance 'localhost\sqlexpress'."
Yes - I switched to using a Windows Authentication connection and it works now. So the answer is Yes, debugging works with SQL Express.
I believe the Express version does not have the debugger. I personally have never found the debugger of value anyway because problems with t-sql tend to be of the "did I get correct results" variety (which are often debugged by trying different variation of where clauses and joins until you find the culprit).
They are often do not concern problems of state while stepping through a series of steps. If you are doing something with many steps in one proc, then add a test or debug variable and write code to populate up what you want to see at that point in time (might be a variable, might be a select query, just depends on what you are trying to do) when running in test mode.

Why only some users get the error: "Connection is busy with results for another command"

I have a Delphi Application that is connected to a SQL Server db using SDAC component from DevArt, we have 200 installations of the software and only to a customer, with some users, I notice the following error:
"Connection is busy with results for another command" = "La connessione รจ occupata dai risultati di un altro comando".
SQL vers.: SQL Server 2008 R2 Express with filestream full enabled
My application create both db users and SQL account logins:
creating a new user, then there aren't problems
changing user code in my application, it means that another db user and SQL account login is created, I have the error
this problem happens only with some users, not all ones
What I've already tried without luck:
deleted and re-installed database
uninstalled and re-installed SQL Server Instance
checked users/account properties in SQL Server (all ok)
If you need specific infos please tell me
------------NEW INFORMATIONS------------
I checked better all the Instance properties from Studio Management and I've noticed that CPU's are not checked (see image below).
Instead in all the other normal installations of SQL Server, I see filled checkboxes.
Could it be the problem?
I hope this help you to help me...
The "Connection is busy with results for another command" error means that there are at least two queries that use the same connection. This problem can occur if you are using one connection in several threads. To solve the problem in this case, you should have connection (the TMSConnection component) in each thread.
Also, this problem can occur if you set the TCustomMSDataSet.FetchAll property to False. When FetchAll=False, execution of such queries blocks the current session. In order to avoid blocking OLEDB creates additional session that can cause the "Connection is busy with results for another command" error. To solve the problem in this case, you should set the TMSConnection.Options.MultipleActiveResultSets property to True. The MultipleActiveResultSets property enables support for the SQL Server Multiple Active Result Sets (MARS) technology. It allows applications to have more than one pending request per connection, and, in particular, to have more than one active default result set per connection. Please note that the MultipleActiveResultSets property works only when SQL Native Client is used. Therefore, you should also set the TMSConnection.Options.Provider property to prNativeClient.
Just wanted to correct dataol's answer and say that MARS_Connection should be set to "Yes" instead of "True" to enable Multiple Active Result Sets. At least on SQL Server 2012 if you are using a DSN file:
[ODBC]
DRIVER=SQL Server Native Client 11.0
DATABASE=MYDBNAME
WSID=
Trusted_Connection=Yes
SERVER=
MARS_Connection=Yes
To provide Multiple Active Result Set (MARS) support to a SQL connection using the MSSQL driver, you must add a key called Mars_Connection and set its value to True.
#ienax_ridens, I recently encountered the same problem using the same tools (Delphi and Devart-SDAC).
In my case one specific query giving two results sets.
My TMSQuery was
If Condition= 1
begin
Select * from #TempTable1
end else
begin
-- Some more stuff
Insert INTO #TempTable2
--
--
End
Select * from TempTable1 -- here is the problem
so in case of Condition = 1 it was giving two results sets and causing "Connection is busy with results for another command"
I hope this helps you.
Edit: I realized you post is quite old, please share what you did to resolve this error
I had the same problem and solved installing the microsoft odbc driver 11 (msodbcsql) (https://www.microsoft.com/pt-br/download/confirmation.aspx?id=36434).
Check your compatibility mode i just ran into this when we moved from 2008 to 2016 db we had to set it to 2012 compatibility mode.
I had this problem when I found that my runtime DLL was in the environment path and the program folder. It was a runtime issue and nothing with the program.

Microsoft OLE DB Provider for SQL Server error '80040e09'

I am having to modify an old web project that us using classic asp. There are actually 2 different projects that are clones of each other, they just point to different databases.
I modified the code from the first project (asp, db, stored procs etc.) and it all works great.
I then copied all that code to the other project since they are clones. All works just fine there too. I can execute the stored procs in query analyzer and all the data comes back as expected and it shows up on the display asp pages.
When i hit the edit button on the page I get the "Microsoft OLE DB Provider for SQL Server error '80040e09'" and it shows the select part of the query in the error window.
I dont get anything about permissions etc.. If I view the page source the data is actually in there. I am really confused as to what is going on.
Anyone have any suggestions or things to look for.
Thanks
This appears to be a permissions error based on the usual meanings of this error code.
I would manually log in to the database using the same credentials you have configured in your application's connection string. Then run the same query and see what happens.

Connect to the same database, but as a another user, without hardcoding a connection string

Can I use OPENDATASOURCE (or another mechanism) from a Stored Procedure to connect to the same database as a different user? If so, how?
The database is meant to be deployed to several customers, and replicated by them as many times as they want to, etc. For this reason, I CANNOT HARDCODE the database server's name or the database's name.
(I tried using OPENDATASOURCE, but it only accepts hardcoded connection strings.)
Might EXECUTE AS work in your situation? http://msdn.microsoft.com/en-us/library/ms181362.aspx
You can set up a Linked Server to connect to the remote server using the login's current security context (or other options as it applies to your situation).
From your stored procedure, you could access it with something like SELECT * FROM mylinkedservername.mylinkedserverdatabase.dbo.mytable
But you say you want to connect to the same database but using a different login? You're looking for impersonation. Perhaps you can do this making a Linked Server that references itself, I haven't tried it. Search Microsoft Help documentation for how to set it up normally and test if it does what you're looking to do.

How to change MS SQLServer authenticated login without closing and reopening the connection?

I have a connection to a Microsoft SQL Server and want the change the connection authenticated user. Is it possible to do it without closing and reopening the connection?
The ideal is something like Oracle set role feature.
I'd love if the solution also works for SQL Server 2000.
You might want to take a look at app roles (sp_setapprole), but you must be aware of consequences being that once the context is changed (e.g. the role is set), it can't be reverted with SQL Server 2000 (it's possible with 2005). The result of this is that the connection is effectively useless when closed in your code, e.g. it can't be returned to the pool and reused, which leads to scalability issues.
Otherwise it is not possible to change the security context once it has been established.
As far as I know SQL Server is very distinct on the account that is passed is the authenticated context. Take Enterprise Manager and other tools for example you must disconnect and re-connect to change users.
Plus looking at the way connection pooling works, it indicates that the connection itself is cached user specific, so if you changed executing parties part way through it would cause major problems with security.
So the short answer, no, it isn't possible as far as I know.
Depending on what you are doing, EXECUTE AS may help you out here. This allows you to execute SQL in the context of another user in a similar fashion to the RUN AS available from the Windows shell. The profiler and audit tracing in SQL Server allows you to see both the original user and which context a statement is run under.
EXECUTE AS USER = 'newuser';
SELECT ... <-- SQL code from under the context of newuser
REVERT;
Note: This is not available under SQL Server 2000 and was added because of requests like yours.

Resources