«default» показывает, что для процедуры или функции задано слишком много аргументов; - PullRequest
0 голосов
/ 24 сентября 2018

Общая цель

Переписать часть веб-сайта, открытую для давних клиентов, которая по-прежнему полагается на выполнение запроса в формате SQL и в настоящее время работает должным образом:

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

Где 162611является целым числомЗатем цель состоит в параметризации запроса с использованием объекта command и добавлении параметров с использованием метода .Parameters.Append .CreateParameter .

Кроме того, вторичная цель состоит в том, чтобы в конечном итоге добавить дополнительные параметры для ограничения объема запроса, но я даже не дошел до этого поста.

Проблема

При выполнении запроса с использованием objConnection.Execute хранимая процедура выполняется, как ожидается, с одним параметром, целым числом (см. Выше).При выполнении запроса с использованием команды recordsource.Open Я получаю сообщение:

  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

Как уже упоминалось, когда я запускаю это, я получаю: «Процедура или функция spNewPayments имеет слишком много аргументов, указанных» Это происходит в строке rsPmts.Open cmd

Я прослеживаю использование Profiler в MS SQL Server, чтобы увидеть, как сервер отвечает, и я вижу:

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

Ага!Похоже, что он передает два параметров, первый параметр как по умолчанию .А?Что это такое?Как оно туда попало?

Очевидно, это вызвано слишком большим количеством параметров, но я не думаю, что мой код добавляет два параметра, только один.

Эта ошибка также появляется, когда люди по неосторожности зацикливаются, но я еще даже не дошел до зацикливания.Я планирую просмотреть цикл позже.

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

.Parameter.Refresh() заставляет ADO запрашивать параметры у SQL Server, что является дополнительной нагрузкой, которую вы можете увидеть в предоставленной вами трассировке 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 https://stackoverflow.com/q/7903268/692942).
*/
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(), фактически удвоив параметр @claim_id в коллекции Parameters, в результате чего он получил бы Too many arguments.

Итак, исправление в вашем примере кода - удалить;

.Parameters.Refresh

Полезные ссылки

0 голосов
/ 24 сентября 2018

Есть две вещи, на которые я обычно смотрю, которые должны это исправить.

Первым задается для свойства CommandType объекта ADODB.Command значение adCmdStoredProc следующим образом:

cmd.CommandType = adCmdStoredProc 

Но вы, возможно, уже сделали это на этомстрока:

.CommandType = 4

Я просто не знаю по памяти, какое значение имеет константа adCmdStoredProc.

Другой элемент помещает заполнитель непосредственно в текст команды:

.CommandText = "spNewPayments @claim_id"

Это лучше всего подходит для adCmdText CommandType и обычно не требуется или не полезно, если CommandType было установлено на adCmdStoredProc, так что это ситуация «один или другой».Я видел, как это эффективно выполняется в обоих направлениях.

Опять-таки, вы можете захотеть .Parameters.Clear, а не .Parameters.Refresh, но, поскольку вы только что создали объект, он вам тоже не нужен, и это был очень долгое время с тех пор, как я прошел ADO старой школы.

...