SQL Server Stored Procedure via VBA and ADODB

Jaymond Flurrie

Well-known Member
Joined
Sep 22, 2008
Messages
919
Office Version
  1. 365
Platform
  1. Windows
Hi,


I'm creating my first stored procedure ever and it looks relatively good so far. The problem is with passing the parameters, more exactly:
Arguments are of wrong type, are out of acceptable range, or are in confilict with one another


The essential part of the stored procedure looks like:
Code:
CREATE PROC GetUserAuthForApp
@User varchar(7),
@application int
AS


while the essential code calling it from VBA looks like:


Code:
Dim strConn As String 'Connection string to SQL Server
Dim strSQLtoExecute As String 'SQL query string to execute
Dim oConn As ADODB.Connection 'Object for connecting
Dim rs As ADODB.Recordset 'Object for recordset
Dim cmd As ADODB.Command
Dim prmUser As ADODB.Parameter
Dim prmApplication As ADODB.Parameter
Dim stProcName As String 'Stored Procedure name


Function LoadAuthorizationInfoFromSQL(iApp As Integer, strUser As String) As Variant
    'Define connection string and open the connection
    strConn = ConnectToSQL()
    
    'Initialize variables for database connections
    Set oConn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    Set cmd = New ADODB.Command
    
    oConn.Open strConn
     
    stProcName = "GetUserAuthForApp" 'Define name of Stored Procedure to execute.
    cmd.CommandType = adCmdStoredProc 'Define the ADODB command
    cmd.ActiveConnection = oConn 'Set the command connection string
    cmd.CommandText = stProcName 'Define Stored Procedure to run
    
    Set prmUser = cmd.CreateParameter("@User", adVarChar, adParamInput, 7)
    cmd.Parameters.Append prmUser
    Set prmApplication = cmd.CreateParameter("@application", adInteger, adParamInput)
    cmd.Parameters.Append prmApplication
    
    prmUser.Value = "'" & strUser & "'" 'Tried also without quotes, no difference
    prmApplication.Value = iApp
        
    'Execute stored procedure and return to a recordset
    rs.Open cmd.Execute


and in that rs.Open comes that error.

What have I done wrong, how do I fix it?
 

Excel Facts

Which came first: VisiCalc or Lotus 1-2-3?
Dan Bricklin and Bob Frankston debuted VisiCalc in 1979 as a Visible Calculator. Lotus 1-2-3 debuted in the early 1980's, from Mitch Kapor.
This is the latest:

After quite a bit of fight, it finally works from SQL Server Management Studio - but not from VBA


In SQL Server Management Studio I can run it like this:
Code:
USE [MyDatabase]
GO


DECLARE	
@return_value int,
@application int,
@user varchar(7)
EXEC
@return_value = [dbo].[GetUserAuthForApp]
@user = 'kilar', 
@application = 1
GO




From VBA, this doesn't work:
Code:
Function LoadAuthorizationInfoFromSQL(iApp As Integer, strUser As String) As Variant


Dim oConn As ADODB.Connection 'Object for connecting
Dim rs As ADODB.Recordset 'Object for recordset
Dim cmd As ADODB.Command
Dim prmUser As ADODB.Parameter
Dim prmApplication As ADODB.Parameter
Dim stProcName As String
    
    'Define connection string and open the connection
    strConn = ConnectToSQL()
    
    'Initialize variables for database connections
    Set oConn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    Set cmd = New ADODB.Command
    
    oConn.Open strConn
     
    stProcName = "[MyDatabase].[dbo].[GetUserAuthForApp]"
    
    cmd.CommandType = adCmdStoredProc 'Define the ADODB command
    cmd.ActiveConnection = oConn 'Set the command connection string
    cmd.CommandText = stProcName 'Define Stored Procedure to run
    
    Set prmUser = cmd.CreateParameter("@user", adVarChar, adParamInput, 7)
    prmUser.Value = "kilar"
    cmd.Parameters.Append prmUser
    
    Set prmApplication = cmd.CreateParameter("@application", adInteger, adParamInput)
    prmApplication.Value = 1
    cmd.Parameters.Append prmApplication
    
        
    'Execute stored procedure and return to a recordset
    rs.Open cmd.Execute
'already crashed by this point


The stored procedure looks like:
Code:
USE [MyDatabase]
SET NOCOUNT ON
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[GetUserAuthForApp]
@user varchar(7),
@application int
AS
DECLARE @tempauthtable varchar(max);
DECLARE @querystring varchar(max);


SET @tempauthtable = '##UserAuthForApp_' + @user


SET @querystring =
'IF NOT EXISTS(SELECT * FROM tempdb.sys.objects WHERE name = ''' + @tempauthtable + ''') 
CREATE TABLE ' + @tempauthtable + 'tablestructurehere';
EXEC (@querystring);


--building a dynamic temp table here about 150 rows cut out
EXEC (@querystring);
SET @querystring = 'SELECT * FROM ' + @tempauthtable;
EXEC (@querystring);


Error is still:
"Arguments are of wrong type, are out of acceptable range, or are in confilict with one another"
 
Upvote 0
Your open statement is incorrect apart from anything else that might be an issue. It should be
Code:
Set rs = cmd.execute

Also your parameters appear to be both input and output so the direction should be adParamInputOutput rather than adParamInput.
 
Last edited:
Upvote 0
Your open statement is incorrect apart from anything else that might be an issue. It should be
Code:
Set rs = cmd.execute

Also your parameters appear to be both input and output so the direction should be adParamInputOutput rather than adParamInput.



Sounds logical. I'll let you know if this alone solved the whole system, but thanks already, I'm sure this will get me adForward :)
 
Upvote 0
Your open statement is incorrect apart from anything else that might be an issue. It should be
Code:
Set rs = cmd.execute

Also your parameters appear to be both input and output so the direction should be adParamInputOutput rather than adParamInput.

It got me further, but now it insists that the recordset is closed. rs.open doesn't open it either.
 
Upvote 0
At what point does it say the recordset is closed?
 
Upvote 0
When I try to do anything with the recordset. For example, as I have this kind of code in VBA:

Code:
Function LoadAuthorizationInfoFromSQL(iApp As Integer, strUser As String) As Variant    
    'Define connection string and open the connection
    strConn = ConnectToSQL()
    
    'Initialize variables for database connections
    Set oConn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    Set cmd = New ADODB.Command
    
    'One possible error here can be caused if user has just changed the password to company network and hasn't logged off and back in after that!
    oConn.Open strConn
     
    stProcName = "thenameofmystoredprocedurehere" 'Define name of Stored Procedure to execute.
    
    cmd.CommandType = adCmdStoredProc 'Define the ADODB command
    cmd.ActiveConnection = oConn 'Set the command connection string
    cmd.CommandText = stProcName 'Define Stored Procedure to run
    
    Set prmUser = cmd.CreateParameter("@user", adVarChar, adParamInput, 7)
    prmUser.Value = strUser
    cmd.Parameters.Append prmUser
    
    Set prmApplication = cmd.CreateParameter("@application", adInteger, adParamInput)
    prmApplication.Value = iApp
    cmd.Parameters.Append prmApplication
    
    Set rs = cmd.Execute
    Range("F1").CopyFromRecordset rs

That last row gives the error. When I put there as the second to last row rs.open, no error is given, but the rs remains closed. rs.Status says same "Operation not allowed when the object is closed" and rs.state returns 0.

Just in case it matters, the end of the stored procedure looks now like

Code:
SET @querystring = 'SELECT * FROM ' + @tempauthtable;
EXEC (@querystring);

In SQL Server it lists nicely the results.

I can work around this by making that stored procedure end with a select into, running that, selecting all from there and dropping the table, but this requires a) three queries and b) an actual table instead of table variable so I would really prefer just a way to read that recordset.

Oh, also, when using that code with inputoutput like you adviced, so like this:
Code:
    Set prmUser = cmd.CreateParameter("@user", adVarChar, adParamInputOutput, 7)    prmUser.Value = strUser
    cmd.Parameters.Append prmUser
    
    Set prmApplication = cmd.CreateParameter("@application", adInteger, adParamInputOutput)
    prmApplication.Value = iApp
    cmd.Parameters.Append prmApplication

I get error "The formal parameter "@user" was not declared as an OUTPUT parameter, but the actual parameter passed in requested output"

I'm not sure what the output points to. Adodb?
 
Last edited:
Upvote 0
That's my fault - I didn't see the rest of the SP that you posted later. Those aren't output parameters at all.

I'm afraid there's far too much going on there for me to debug it from here. As it's an ADO/SQL issue, not an Excel one, you might be better served in a more appropriate forum.
 
Upvote 0
That's my fault - I didn't see the rest of the SP that you posted later. Those aren't output parameters at all.

I'm afraid there's far too much going on there for me to debug it from here. As it's an ADO/SQL issue, not an Excel one, you might be better served in a more appropriate forum.

Ok, will do. do you have any recommendations as Adodb forums?

But thanks anyway, you solved it to the point where it at least works if nothing else!
 
Upvote 0
Not specifically but you could try one of the Microsoft Answers forums.
 
Upvote 0

Forum statistics

Threads
1,215,066
Messages
6,122,948
Members
449,095
Latest member
nmaske

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top