Не удается передать строку хранимой процедуре

Вот моя хранимая процедура...

alter PROCEDURE ReplyToEmailConfirmation 
    @uniqueKey varchar(36)
AS
BEGIN

Print 'Hello World!'
END

Вот код...

Set cmd = Server.CreateObject("ADODB.Command")
With cmd
    .ActiveConnection = getConfigValue("ASPClassicConnectionString")
    .CommandType = adCmdStoredProc
    .CommandText = "[ReplyToEmailConfirmation]"

    .Parameters.Append .CreateParameter("@uniqueKey", adVarChar, adParamInput, 36, "dc8d8bfd-ea3a-4ad9-9f2d-92831eb2655a")

End With

cmd.Execute

Вот ошибка...

Ошибка ADODB.Command «800a0bb9»

Аргументы имеют неправильный тип, находятся вне допустимого диапазона или конфликтуют друг с другом.

Как заставить это работать? Намерение состоит в том, чтобы использовать adGUID, но я решил попробовать adVarChar, чтобы сузить ошибку.


person Ian Warburton    schedule 08.11.2016    source источник
comment
похоже, вы можете автоматически заполнить информацию о параметрах из хранимой процедуры с помощью .Parameters.Refresh msdn.microsoft. com/en-us/library/ms676516   -  person Slai    schedule 08.11.2016
comment
@Slai не делайте этого, для получения информации о параметрах требуется дополнительная поездка на сервер, что не рекомендуется.   -  person user692942    schedule 08.11.2016
comment
Вам не хватает параметра Size в методе CreateParameter() попробуйте .Parameters.Append .CreateParameter("@uniqueKey", adVarChar, adParamInput, 100). Также попробуйте сообщить ADODB, что вы выполняете хранимую процедуру, установив .CommandType = adCmdStoredProc.   -  person user692942    schedule 08.11.2016


Ответы (2)


Если вы читали с документацией для CreateParameter() все становится ясно;

Если вы укажете тип данных переменной длины в аргументе Type, вы должны либо передать аргумент Size, либо установить свойство Size объекта Parameter, прежде чем добавлять его в коллекцию Parameters; в противном случае возникает ошибка.

Поскольку вы передаете VARCHAR, который является типом данных переменной длины, вы должны указать Size при вызове CreateParameter().

Dim cmd

Set cmd = Server.CreateObject("ADODB.Command")
With cmd
    'Let the cmd deal with the connection.
    .ActiveConnection = getConfigValue("ASPClassicConnectionString")
    .CommandText = "[ReplyToEmailConfirmation]"
    .CommandType = adCmdStoredProc
    Call .Parameters.Append(.CreateParameter("@uniqueKey", adVarChar, adParamInput, 100))
    .Parameters("@uniqueKey") = "dc8d8bfd-ea3a-4ad9-9f2d-92831eb2655a"
End With
Call cmd.Execute()

'Tidy up memory
Set cmd = Nothing

Также включен CommandType из adCmdStoredProc, который сообщает ADO интерпретирует эту команду как вызов хранимой процедуры, без нее значение по умолчанию равно adCmdUnknown, что означает, что ADO должна попытаться определить, что представляет собой команда, которая, однако, незначительна, добавляет ненужные накладные расходы.

Также не большой поклонник создания экземпляра объекта ADODB.Connection только для выполнения объекта ADO.Command, что означает, что вам придется самостоятельно закрывать ADODB.Connection. Вместо этого позвольте ADODB.Command сделать это за вас, передав строку соединения, позволяя ему создать соединение и уничтожить его самостоятельно. Предполагая, что getConfigValue("ASPClassicConnectionString") возвращает строку соединения, вы можете передать ее непосредственно ActiveConnection, а ADODB.Command создаст экземпляр соединения и избавится от него.


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

person user692942    schedule 08.11.2016
comment
Я уже пробовал параметр размера, и он тоже не сработал. Я обновил вопрос. - person Ian Warburton; 08.11.2016
comment
Кроме того, я удалил .CommandType = adCmdStoredProc, потому что он, похоже, вызывал ту же ошибку. - person Ian Warburton; 08.11.2016
comment
На самом деле, если я удалю параметр с обоих концов, установка типа команды приведет к этой ошибке. - person Ian Warburton; 08.11.2016
comment
@IanWarburton Да, как вы уже догадались, вам нужны именованные константы ADODB, определяющие либо вручную с помощью Const name = value, либо с помощью METADATA (см. ссылку в ответе), чтобы импортировать библиотеку типов для всего вашего веб-приложения и никогда не определять их опять таки. - person user692942; 08.11.2016

Я не включил adovbs.inc для констант adCmdStoredProc, adVarChar и adGUID. Дох.

person Ian Warburton    schedule 08.11.2016
comment
Вы используете это в классическом ASP? VBScript не поддерживает включения, если вы планируете использовать МЕТАДАННЫЕ. - person user692942; 08.11.2016
comment
Да, классический АСП. Под включением я подразумеваю... <!--#include virtual="/include/adovbs.asp"-->. - person Ian Warburton; 08.11.2016
comment
Было бы полезно иметь тег asp-classic в вопросе, чтобы мы понимали контекст. Если бы я знал, я бы включил информацию об использовании METADATA в свой ответ. - person user692942; 08.11.2016
comment
Этот тег стоит в вопросе! Или вы его добавили? - person Ian Warburton; 08.11.2016
comment
В какой другой среде я мог бы использовать VBScript и ADO? - person Ian Warburton; 08.11.2016
comment
Их много, VBScript используется в качестве языка сценариев для множества разных хостов. Но чаще всего вы можете вызывать его с помощью cscript.exe и wscript.exe на большинстве компьютеров под управлением ОС Windows. Да, я добавил тег, вы можете увидеть ревизию здесь. - person user692942; 08.11.2016