'default' 出现这样的情况,过程或函数指定的参数太多;

'default' showing up so, procedure or function has too many arguments specified;

总体目标

重写暴露给长期客户的网站部分仍然依赖于 SQL 格式的查询执行并且目前按预期工作:

SQLQuery = "exec spNewPayments " & "162611"
  Set rsPmts = objConnection.Execute(SQLQuery)

其中 162611 是一个整数。然后目标是使用 command 对象参数化查询并使用 .Parameters.Append .CreateParameter 技术添加参数。

此外,次要目标是最终 添加 附加参数以限制查询的范围,但我什至没有在这个 post 中走那么远。

问题

当使用 objConnection.Execute 进行 运行ning 查询时,存储过程 运行s 如预期的那样带有一个参数,一个整数(见上文) ).当使用 recordsource.Open 命令 运行ning 查询时 我收到消息:

  spNewPayments has too many arguments specified
  Code: 80040E14

存储过程是使用以下方法创建的:

USE [maindb]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER OFF
GO

CREATE PROCEDURE [dbo].[spNewPayments] @claim_id int = NULL AS
select *
FROM dbo.objectTest co
WHERE co.foreign_id = @claim_id;

GO

我目前用来测试的VBScript是:

Dim strCnxn 
strCnxn = "DSN=myDSN"
Dim objConnection
Set objConnection = CreateObject("ADODB.Connection")  
objConnection.Mode = acModeRead
objConnection.Open strCnxn

Dim cmd
Set cmd = CreateObject("ADODB.Command")
Dim rsPmts 
Set rsPmts = CreateObject("ADODB.Recordset")
With cmd
.ActiveConnection = objConnection

.CommandType = 4
.CommandText = "spNewPayments"

.Parameters.Refresh

.Parameters.Append .CreateParameter("@claim_id", 3, , , 162611)

End With

rsPmts.Open cmd
rsPmts.Close 

Set rsPmts = Nothing
 Set objConnection = Nothing
 Set cmd = Nothing

如前所述,当我 运行 这个时,我得到: "Procedure or function spNewPayments has too many arguments specified" 它出现在行 rsPmts.Open cmd

我在 SQL Server MS 中使用 Profiler 进行跟踪以查看服务器如何响应,我看到:

declare @p1 int
set @p1=180150003
declare @p3 int
set @p3=8
declare @p4 int
set @p4=1
declare @p5 int
set @p5=2
exec sp_ddopen @p1 output,N'sp_sproc_columns',@p3 output,@p4 output,@p5 output,N'spNewPayments',NULL,NULL,NULL
select @p1, @p3, @p4, @p5
go
exec sp_cursorfetch 180150003,2,1,1
go
exec sp_cursorfetch 180150003,2,1,1
go
exec sp_cursorfetch 180150003,2,1,1
go
exec sp_cursorclose 180150003
go
exec spNewPayments default,162611
go

啊哈!它似乎传递了 两个 参数,第一个参数为 default。嗯?那是什么?它是怎么进去的?

很明显,这是由于参数太多造成的,但我不认为我的代码添加了两个参数,只是一个。

当人们无意中进入循环时,似乎也会出现此错误,但我什至还没有进入循环。我打算稍后循环 recordsource

我通常会查看两件事情来解决这个问题。

首先是将 ADODB.Command 对象的 CommandType property 设置为 adCmdStoredProc,如下所示:

cmd.CommandType = adCmdStoredProc 

但您可能已经在这一行中完成了:

.CommandType = 4

我只是凭记忆不确定 adCmdStoredProc 常量有什么值。

另一种是将占位符直接放在命令文本中:

.CommandText = "spNewPayments @claim_id"

这最适合 adCmdText CommandType,如果 CommandType 设置为 adCmdStoredProc,通常不需要或没有帮助,所以这是一个或另一个情况。我已经看到它有效地完成了这两种方式。

再看一遍,您可能想要 .Parameters.Clear 而不是 .Parameters.Refresh,但是由于您刚刚创建了您不应该需要的对象而且它已经 非常 自从我完成老派的 ADO 以来已经很久了。

.Parameter.Refresh() 导致 ADO 从 SQL 服务器请求参数,这是一种开销,您可以在您提供的 SQL Profiler 跟踪中看到。调用此方法会自动填充 .Parameters 集合,但不建议用于生产,因为每次执行时都会请求服务器填充集合。

跟踪中的这些行是由于 .Parameters.Refresh 调用;

-- Declaration and setting of temporary varibles
declare @p1 int
set @p1=180150003
declare @p3 int
set @p3=8
declare @p4 int
set @p4=1
declare @p5 int
set @p5=2
/*
Execution of sp_sproc_columns to get the expected parameters from the
spNewPayments stored procedure (see 
*/
exec sp_ddopen @p1 output,N'sp_sproc_columns',@p3 output,@p4 output,@p5 output,N'spNewPayments',NULL,NULL,NULL
select @p1, @p3, @p4, @p5
go
-- Use cursor to loop through results.
exec sp_cursorfetch 180150003,2,1,1
go
exec sp_cursorfetch 180150003,2,1,1
go
exec sp_cursorfetch 180150003,2,1,1
go
-- Close the cursor.
exec sp_cursorclose 180150003
go

错误的原因是因为您随后使用.Parameters.Append()CreateParameter() 方法手动添加了参数。如果您没有首先调用 Refresh() 实际上将 Parameters 集合中的参数 @claim_id 加倍导致它具有 Too many arguments.

因此,您的代码示例中的解决方法是删除;

.Parameters.Refresh

有用的链接

  • Using Stored Procedure in Classical ASP .. execute and get results
  • Error trying to call stored procedure with prepared statement
  • Using METADATA to Import DLL Constants (如果您使用的是 Classic ASP 强烈推荐这种方法来使用命名常量)