1

I'm trying to use a prepared statement to call a stored procedure (using ADODB with classic ASP), but when I set CommandType I get the following error:

ADODB.Command error '800a0bb9'

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.

I have the following code:

With Server.CreateObject("ADODB.Command")
    .ActiveConnection = db 'this is initialized prior
    .CommandType = adCmdStoredProc
    .CommandText = "procName"
End With

The prepared statement name is correct (I'm able to call it just by executing the string), and if I leave out the .CommandType and try calling .Execute, I get an error specifying:

Procedure or function 'procName' expects parameter '@ParamName', which was not supplied.

Even if I leave out the CommandType, I have no idea how to actually add the parameter (something along the following lines just results in the original error about arguments of the wrong type):

.Parameters.Append .CreateParameter("@ParamName",adVarChar,adParamInput,50,param)

I've also tried the following and got an error "Item cannot be found in the collection corresponding to the requested name or ordinal."

.Parameters.Refresh
.Parameters(0) = param

I've looked at several examples of how to call stored procedures using prepared statements, and it looks like I'm using the right syntax, but anything I try seems to result in some kind of error. Any help would be greatly appreciated.

user692942
  • 16,398
  • 7
  • 76
  • 175
Devin
  • 53
  • 1
  • 6
  • So your sproc is called 'preparedStatementName'? – Rob Feb 11 '14 at 00:13
  • Not actually. I used it as a placeholder in my post because I'm not sure if my job is okay with me posting our proc names. I should have used something like "procName" but words failed me at that moment. – Devin Feb 11 '14 at 01:10
  • 1
    post your stored procedurre or at least the expected Parameters of it – ulluoink Feb 11 '14 at 06:05
  • @ulluoink: I don't have access to the definition of the stored procedure. – Devin Feb 11 '14 at 15:49
  • @ulluoink I was told what parameters the procedure expects, but I have no access to the actual definition. – Devin Feb 11 '14 at 16:24
  • @Nikker The parameters will be enough that is all we mean, as long as you are confident they are passed as the procedure expects then you're good to go. Glad it worked for you. – user692942 Feb 11 '14 at 16:29

2 Answers2

3

You want something like this (untested)

Dim cmd, rs, ars, conn

Set cmd = Server.CreateObject("ADODB.Command")

With cmd
  'Assuming passing connection string if passing ADODB.Connection object
  'make sure you use Set .ActiveConnection = conn also conn.Open should
  'have been already called.
  .ActiveConnection = conn
  'adCmdStoredProc is Constant value for 4 (include adovbs or 
  'set typelib in global.asa)
  .CommandType = adCmdStoredProc
  .CommandText = "dbo.procName"
  'Define parameters in ordinal order to avoid errors
  Call .Parameters.Append(.CreateParameter("@ParamName", adVarChar, adParamInput, 50))

  'Set values using parameter friendly name
  .Parameters("@ParamName").Value = param

  'Are you returning a recordset?
  Set rs = .Execute()
  'Populate array with data from recordset
  If Not rs.EOF Then ars = rs.GetRows()
  Call rs.Close()
  Set rs = Nothing
End With
Set cmd = Nothing

It is important to remember that the friendly name (as I rule I tend to match my parameter names in my stored procedure to my friendly names in ADO) you give your parameter means nothing to the stored procedure as ADO passes the parameters ordinally and nothing more, the fact you get the error;

Procedure or function 'procName' expects parameter '@ParamName', which was not supplied.

Suggests that the stored procedure is expecting your @ParamName parameter (defined in your stored procedure) value to be passed from ADO in a different ordinal position, which usually means you have not defined all your parameters or passed all the parameter values in the position they are expected.

You can also do a shortened version if your confident of your ordinal positioning and parameter requirements

With cmd
  .ActiveConnection = conn
  .CommandType = adCmdStoredProc
  .CommandText = "dbo.procName"

  'Pass parameters as array following ordinal position.
  Set rs = .Execute(, Array(param))
  'Populate array with data from recordset
  If Not rs.EOF Then ars = rs.GetRows()
  Call rs.Close()
  Set rs = Nothing
End With
Set cmd = Nothing

Working with a 2-dimensional array is easy and negates the overhead of working directly with a ADODB.Recordset.

Dim row, rows

If IsArray(ars) Then
  rows = UBound(ars, 2)
  For row = 0 To rows
    Response.Write "First column from row " & row & " = " & ars(0, row) & "<br />"
  Next
Else
  Response.Write "No data to return"
End If

Links

user692942
  • 16,398
  • 7
  • 76
  • 175
  • I can't even get as far as specifying ".CommandType = adCmdStoredProc" without getting an error about arguments. – Devin Feb 11 '14 at 15:47
  • @Nikker see my answer, I tried to make it clear with comments – meda Feb 11 '14 at 15:49
  • @Nikker That can easily be fixed by added the ADO constants file using an `#include` or setting it globally using your `global.asa` file - see [this article](http://www.4guysfromrolla.com/webtech/110199-1.shtml) – user692942 Feb 11 '14 at 16:14
  • The thing about [tag:ado] in [tag:classic-asp] is there are numerous ways to approach it but over the years i've found these methods to be the best - opinion. Obviously [tag:ado.net] is a whole different ball game. – user692942 Feb 11 '14 at 16:28
  • exactly, so many ways to accomplish the same thing that you wonder which is the right way. I dont code in classic anymore thanks god. it was always vbscript causing issue. – meda Feb 11 '14 at 16:30
0

Here is how you call a stored procedure in ASP classic:

'Set the connection
'...............

'Set the command
DIM cmd
SET cmd = Server.CreateObject("ADODB.Command")
SET cmd.ActiveConnection = Connection

'Set the record set
DIM RS
SET RS = Server.CreateObject("ADODB.recordset")

'Prepare the stored procedure
cmd.CommandText = "procName"
cmd.CommandType = 4  'adCmdStoredProc

'Assign value to the parameter
cmd.Parameters("@ParamName ") = ParamValue 

'Execute the stored procedure
RS = cmd.Execute
SET cmd = Nothing

'You can now access the record set
if (not RS.EOF) THEN
    data = RS("column_name")
end if

'dispose your objects
RS.Close
SET RS = Nothing

Connection.Close
SET Connection = Nothing
meda
  • 45,103
  • 14
  • 92
  • 122
  • Setting `SET RS = Server.CreateObject("ADODB.recordset")` at the beginning is pointless as `SET RS = cmd.Execute` instantiates your `ADODB.Recordset` anyway. Also `SET cmd = Nothing` will dispose of related objects including the `ActiveConnection`. You could avoid a lot of code if you just passed `SET cmd.ActiveConnection = conn_string` where `conn_string` is your connection string not the `ADODB.Connection` object. – user692942 Feb 11 '14 at 16:21
  • @Lankymart yes you right, its kinda redundant, I was wondering how did you manage to keep your vb comments gray! didnt even know you can do thatthanks alot – meda Feb 11 '14 at 16:23
  • I use the markdown script `` to set the correct syntax highlighting see [this](http://stackoverflow.com/editing-help#comment-formatting) – user692942 Feb 11 '14 at 16:25