【问题标题】:Error trying to call stored procedure with prepared statement尝试使用准备好的语句调用存储过程时出错
【发布时间】:2014-03-08 13:44:44
【问题描述】:

我正在尝试使用准备好的语句来调用存储过程(使用带有经典 ASP 的 ADODB),但是当我设置 CommandType 时出现以下错误:

ADODB.Command 错误“800a0bb9”

参数类型错误、超出可接受范围或相互冲突。

我有以下代码:

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

准备好的语句名称是正确的(我可以通过执行字符串来调用它),如果我省略 .CommandType 并尝试调用 .Execute,我会得到一个错误指定:

过程或函数“procName”需要参数“@ParamName”,但未提供。

即使我省略了 CommandType,我也不知道如何实际添加参数(以下内容只会导致有关错误类型的参数的原始错误):

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

我也尝试了以下方法并收到错误“在与请求的名称或序号相对应的集合中找不到项目。”

.Parameters.Refresh
.Parameters(0) = param

我查看了几个如何使用准备好的语句调用存储过程的示例,看起来我使用了正确的语法,但我尝试的任何操作似乎都会导致某种错误。任何帮助将不胜感激。

【问题讨论】:

  • 所以你的存储过程被称为'preparedStatementName'?
  • 实际上不是。我在帖子中使用它作为占位符,因为我不确定我的工作是否适合我发布我们的 proc 名称。我应该使用“procName”之类的东西,但那一刻让我失望了。
  • 发布您的存储过程或至少它的预期参数
  • @ulluoink:我无权访问存储过程的定义。
  • @ulluoink 我被告知程序需要什么参数,但我无法访问实际定义。

标签: sql stored-procedures vbscript asp-classic adodb


【解决方案1】:

你想要这样的东西(未经测试)

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

重要的是要记住,您给参数的友好名称(我认为我倾向于将存储过程中的参数名称与 ADO 中的友好名称相匹配)对存储的参数没有任何意义程序作为 ADO 按顺序传递参数,仅此而已,您得到错误的事实;

过程或函数“procName”需要参数“@ParamName”,但未提供。

表明存储过程期望您的 @ParamName 参数(在您的存储过程中定义)值从 ADO 以不同的序号位置传递,这通常意味着您尚未定义所有参数或将所有参数值传递到他们预期的位置。

如果你对你的序数定位和参数要求有信心,你也可以做一个缩短的版本

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

使用二维数组很容易,并且消除了直接使用 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

链接

【讨论】:

  • 我什至无法指定“.CommandType = adCmdStoredProc”而不会收到有关参数的错误。
  • @Nikker 看到我的回答,我试着用 cmets 说清楚
  • @Nikker 这可以通过使用#include 添加ADO 常量文件或使用global.asa 文件全局设置来轻松修复 - 请参阅this article
  • classic-asp 中关于ado 的事情是有很多方法可以接近它,但多年来我发现这些方法是最好的 - 意见。显然ado.net 是一个完全不同的球类游戏。
  • 没错,完成同一件事的方法有很多,以至于您想知道哪种方法是正确的。感谢上帝,我不再使用经典代码了。总是 vbscript 导致问题。
【解决方案2】:

这是在 ASP 经典中调用存储过程的方法:

'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

【讨论】:

  • 在开头设置SET RS = Server.CreateObject("ADODB.recordset") 毫无意义,因为SET RS = cmd.Execute 无论如何都会实例化您的ADODB.Recordset。此外SET cmd = Nothing 将处理相关对象,包括ActiveConnection。如果您只传递了SET cmd.ActiveConnection = conn_string,则可以避免大量代码,其中conn_string 是您的连接字符串而不是ADODB.Connection 对象。
  • @Lankymart 是的,你说得对,有点多余,我想知道你是如何设法让你的 vb cmets 保持灰色的!甚至不知道你能做到这一点非常感谢
  • 我使用markdown脚本&lt;!-- language: lang-vb --&gt;来设置正确的语法高亮见this
猜你喜欢
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多