Почему параметр adParamOutput не содержит значения после выполнения - PullRequest
4 голосов
/ 09 ноября 2011

Я использую ASP classic с ADO, подключаясь к SQL Server 2008.

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

Я создаю команду и добавляю параметры

oCmd.CommandType = adCmdStoredProc
...
oCmd.Parameters.Append oCmd.CreateParameter("@MyOutputParam", adInteger, adParamOutput, 4, NULL)

Позже я открываю ридер из этой команды:

oRS.Open oCmd, , adOpenForwardOnly, adLockReadOnly

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

val1 = oCmd("@MyOutputParam")
val2 = oCmd("@MyOutputParam").Value
val3 = oCmd.Parameters("@MyOutputParam").Value

Все три (val1, val2, val3) переменные являются DB NULL.

Я подтвердил, что запуск SP в анализаторе запросов возвращает значение параметра @MyOutputParam:

declare @p33 int
exec usp_GetResultAndOutput 1, 2, 3, @p33 output
select @p33

Возвращает набор моих ожидаемых записей и второй набор записей, показывающий число в одной строке.

Я даже пытался вызвать rs.NextRecordset, прежде чем пытаться получить выходной параметр, но это не сработало.

Есть ли другой способ обработки выходных параметров?

Это нормально, что я возвращаю набор записей и выходные параметры?

Ответы [ 2 ]

5 голосов
/ 09 ноября 2011

Выходные параметры не могут быть извлечены, пока все наборы записей не будут перечислены до конца.Подумайте, как клиент мог бы получить выходное значение параметра до завершения выполнения?Вызов Execute() - это просто начало выполнения, пакет продолжает выполняться на сервере, пока не будут возвращены все результаты.Пока клиент выполняет итерацию по набору результатов, выданному SELECT, пакет выполняет этот SELECT.Значение выходного параметра известно только на конце пакета.Поэтому невозможно узнать значение выходного параметра до завершения пакета, что подразумевает, что все операторы выполнены, что, в свою очередь, требует, чтобы все наборы результатов были использованы (повторены) клиентом.

Это каноническая формапарсинга набора результатов:

do
{
  while (rs.MoveNext)
  {
    // do something with the row
  }
} while (Not rs.NextRecordset Is Nothing)
// now is safe to read the out param
response.write oCmd("@MyOutput")
1 голос
/ 09 ноября 2011

Насколько я могу проверить, единственное, что имеет значение, это CursorLocation. Пока для CursorLocation установлено значение adUseClient (3), к выходным параметрам можно получить доступ в любое время после выполнения. Любое из следующего делает это

oConn.CursorLocation = adUseClient

или

oRs.CursorLocation = adUseClient

Это проверено на SQL 2008 R2, IIS / ASP на Windows 7 и с поставщиком SQLOLEDB.

...