ADO命令参数未传递到存储过程或存储过程'忽略'参数

时间:2014-08-26 14:16:11

标签: sql sql-server vbscript asp-classic ado

更新4

更新了整个问题以反映我的更改。仍然没有工作。

这已经让我烦恼了两天了。我正在更新客户使用的旧订购界面系统,用ASP Classic,VBScript编写。它连接到Windows Server 2003上的SQL数据库。

存储过程

我有一个存储过程,它返回一个托盘代码列表,按客户ID过滤,并可通过托盘代码搜索:

CREATE PROCEDURE dbo.sp_PalletSearch
@CustomerRef        Int,
@SearchQuery        VarChar(15) = '%'
AS

SET NoCount On  
SET @SearchQuery = '%' + COALESCE(@SearchQuery, '%') + '%'

SELECT      p.PalletID,
            p.PalletCode
FROM        dbo.v_PalletSearch p
WHERE       p.CustomerRef   = @CustomerRef
AND         p.PalletCode    LIKE @SearchQuery
ORDER BY    p.PalletCode    ASC

SET NoCount Off
GO

在带有和不带搜索词的SQL查询分析器中,这似乎都可以正常工作:

exec sp_PalletSearch 100, ''exec sp_PalletSearch 100, 'PalletCode'

ASP网页

所以进入网页本身...这是我用来获取记录集的ADO命令,这就是我的问题开始的地方。它只是不会返回任何东西:

Dim strSearchQuery
strSearchQuery = "PalletCode"

Dim objCmd
Set objCmd = Server.CreateObject("ADODB.Command")
objCmd.ActiveConnection = cConn
objCmd.CommandType = adCmdStoredProc
objCmd.CommandText = "sp_PalletSearch"
objCmd.Parameters.Append objCmd.CreateParameter("@CustomerRef", adInteger, adParamInput)
objCmd.Parameters.Append objCmd.CreateParameter("@SearchQuery", adVarChar, adParamInput, 15)
objCmd.Parameters("@CustomerRef").Value = CustomerID
objCmd.Parameters("@SearchQuery").Value = strSearchQuery

Dim objRS
Set objRS = objCmd.Execute
Set objCmd = Nothing


Do While Not objRS.EOF
    Response.Write(objRS("PalletID").Name & ": " & objRS("PalletID").Value & " | " & objRS("PalletCode").Name & ": " & objRS("PalletCode").Value & "<br>")
    objRS.MoveNext
Loop

objRS.Close
Set objRS = Nothing

我试过......

如果我在ADO命令中编辑此行:

objCmd.CommandText = "sp_PalletSearch"

并将其更改为:

objCmd.CommandText = "{call sp_PalletSearch(?, '" & strSearchQuery & "')}"

并删除:

objCmd.CommandType = adCmdStoredProc

所有搜索工作正常。 如果找不到真正的解决方案,我将坚持这一点。


如果我编辑存储过程以获取等于搜索词的托盘代码而不是 LIKE ,并注释掉

--SET @SearchQuery = '%' + COALESCE(@SearchQuery, '%') + '%'

然后我会得到完全匹配。这会告诉我ADO命令正在传递参数ok。 那么为什么存储过程无法获得结果 LIKE @SearchQuery


另外需要注意的是,使用以下代码替换ADO命令可以正常使用托盘代码 LIKE 。我不认为这个片段是一个安全的选项,如果我错了,请告诉我。我宁愿使用参数化命令:

strSQL = "EXECUTE sp_PalletSearch " & CustomerID & ", '" & strSearchQuery & "' "
Set objRS = Server.CreateObject("ADODB.Recordset")
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open cConn
objRS.Open strSQL, objConn  

这是一个很大的问题,但我喜欢有效和正确地做事,我喜欢学习。 我希望你们能帮我解决这个难题。

3 个答案:

答案 0 :(得分:1)

我认为你通过尝试任何事情和一切都会给自己带来更多问题。每次尝试都会使您的语法出现轻微错误(例如错误位置的引号,而不是指定CommandType等)。

如果这有助于我为该存储过程编写代码

Dim cmd, rs, sql
Dim data, rows, row

Set cmd = Server.CreateObject("ADODB.Command")
'Name of your stored procedure
sql = "dbo.sp_PalletSearch"

With cmd
  .ActiveConnection = cConn 'Assuming cConn is a connection string variable
  .CommandType = adCmdStoredProc
  .CommandText = sql
  'Define Stored Procedure parameters
  Call .Parameters.Append(.CreateParameter("@CustomerRef", adInteger, adParamInput, 4))
  Call .Parameters.Append(.CreateParameter("@SearchQuery", adVarChar, adParamInput, 15))
  'First parameter is optional so only pass if we have a value, will default to NULL.
  If Len(CustomerId) > 0 Then .Parameters("@CustomerRef").Value = CustomerID
  .Parameters("@SearchQuery").Value = strSearchQuery
  Set rs = .Execute()

  'Populate 2D-Array with data from Recordset
  If Not rs.EOF Then data = rs.GetRows()

  'Close and Release Recordset from memory
  Call rs.Close()
  Set rs = Nothing
End With
Set cmd = Nothing

If IsArray(data) Then
  rows = UBound(data, 2)
  For row = 0 To rows
    Call Response.Write("Pallet Id: " & data(0, row) & " | Pallet Code: " & data(1, row) & "</ br>")
  Next
End If

答案 1 :(得分:1)

解决

感谢邦德,尤其是Lankymart的帮助。 Lankymart,您使用SQL Profiler的建议有所帮助。我的服务器有旧版本,我想 - Profiler。

我在查看Profiler跟踪时发现了这一点:@SearchQuery = 'bww100052 '

所以我决定在存储过程中强制修剪:LTRIM(RTRIM(@SearchQuery))

存储过程

CREATE PROCEDURE dbo.sp_PalletSearch
@CustomerRef        Int,
@SearchQuery        VarChar(15) = '%'
AS    

SET NoCount On  
SET @SearchQuery = '%' + COALESCE(LTRIM(RTRIM(@SearchQuery)), '%') + '%'

SELECT      p.PalletID,
            p.PalletCode
FROM        dbo.v_PalletSearch p
WHERE       p.CustomerRef   = @CustomerRef
AND         p.PalletCode    LIKE @SearchQuery
ORDER BY    p.PalletCode    ASC

SET NoCount Off
GO

ADO命令

Dim objCmd
Set objCmd = Server.CreateObject("ADODB.Command")
objCmd.ActiveConnection = cConn
objCmd.CommandType = adCmdStoredProc
objCmd.CommandText = "sp_PalletSearch"
objCmd.Parameters.Append objCmd.CreateParameter("@CustomerRef", adInteger, adParamInput)
objCmd.Parameters.Append objCmd.CreateParameter("@SearchQuery", adVarChar, adParamInput, 15)
objCmd.Parameters("@CustomerRef").Value = CustomerID
objCmd.Parameters("@SearchQuery").Value = Trim(strSearchQuery)

Dim objRS
Set objRS = objCmd.Execute
Set objCmd = Nothing

最后

我以为我永远不会解决这个问题,它根本没有任何意义! 我会再对它进行一些测试,但看起来需要修剪变量。我不知道为什么增加了额外的空间。

答案 2 :(得分:-1)

尝试

objCmd.Parameters.Append objCmd.CreateParameter("@SearchQuery", adVarChar, adParamInput, 15, "'PalletCode'")

请注意,“'PalletCode'”内部还有一组额外的单引号。