这已经让我烦恼了两天了。我正在更新客户使用的旧订购界面系统,用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'
所以进入网页本身...这是我用来获取记录集的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
这是一个很大的问题,但我喜欢有效和正确地做事,我喜欢学习。 我希望你们能帮我解决这个难题。
答案 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
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'”内部还有一组额外的单引号。