Кака полусить данные, возвращаемые хранимой процедурой

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
Altair
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.04.2008 (Ср) 13:02

Кака полусить данные, возвращаемые хранимой процедурой

Сообщение Altair » 02.04.2008 (Ср) 13:10

Запускаю хранимую процедуру (Microsoft SQL Server), которая возвращает таблицу с данными.
Однако работать с данными не могу т.к. рекордсет закрыт(State= 0).
Ошибка ADODB.Recordset. Операция не допускается если рекордсет закрыт.
Почему так происходит?
Соединение открыто, с эти проблем нет.

Dim ConnetionString As String
Dim conn As ADODB.Connection
Dim Command As ADODB.Command


Set conn = New ADODB.Connection
Set Command = New ADODB.Command
Set ResRecord = New ADODB.Recordset

conn.ConnectionString = f_ConnectionString()
conn.Open
'обработка ошибок
On Error GoTo ErrLine

Command.ActiveConnection = conn
Command.CommandText = "GRS_REPORT1_PF"
Command.CommandType = adCmdStoredProc

Call Command.Parameters.Append(Command.CreateParameter("@DateEnd", adVarWChar, adParamInput, 20))
Command.Parameters("@DateEnd").Value = "02.02.2008"

Set ResRecord = conn.Execute(Command.CommandText, , CommandTypeEnum.adCmdStoredProc)
Call ResRecord.Open(Command, , ADODB.adOpenDynamic, ADODB.adOpenDynamic, сommandTypeEnum.adCmdStoredProc)

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 02.04.2008 (Ср) 14:41

вот пример:

Код: Выделить всё
Public Function GetRequests(ByVal ModuleID As Integer) As ADODB.Recordset
Dim cmd As ADODB.Command
Dim Rs As ADODB.Recordset
Dim p As ADODB.Parameters

    Set cmd = New ADODB.Command
    cmd.ActiveConnection = GetConnectionString()
    cmd.CommandType = adCmdStoredProc
    cmd.CommandText = "GetRequests"
    Set p = cmd.Parameters
    p.Append cmd.CreateParameter("RETURN_VALUE", adInteger, adParamReturnValue)
    p.Append cmd.CreateParameter("@ModuleID", adSmallInt, adParamInput, , ModuleID)

    Set Rs = New ADODB.Recordset
    Rs.CursorLocation = adUseClient
    Rs.Open cmd, , adOpenStatic, adLockReadOnly

    Set GetRequests = Rs

    Set cmd = Nothing
    Set Rs = Nothing
    Set p = Nothing   
End Function

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 02.04.2008 (Ср) 16:32

Код: Выделить всё
Set ResRecord = conn.Execute(Command.CommandText, , CommandTypeEnum.adCmdStoredProc)
Call ResRecord.Open(Command, , ADODB.adOpenDynamic, ADODB.adOpenDynamic, сommandTypeEnum.adCmdStoredProc)
На лицо две попытки открыть один и тот же рекордсет. Первая не прокатит потому что в Execute нужно передавать текстовый запрос, а передается лишь имя процедуры без параметра. И этим способом возвращаемые параметры не получить.
Во второй adOpenDynamic не может быть четвертым параметром метода Open. Вернее его значение может, но смысл совсем другой. И последний параметр не нужен - то, что это хранимая процедура, было указано в Command.CommandType = adCmdStoredProc. Но в принципе рекордсет должен был открыться. А раз не открылся, значит в начале хранимой процедуры нет текста set nocount on.

Konst_One
p.Append - лишние. Если указать тип adCmdStoredProc, имя и соединение, то параметры создадутся сами - в хранимке они описаны.
Лучший способ понять что-то самому — объяснить это другому.

HandKot
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 283
Зарегистрирован: 28.06.2006 (Ср) 13:34
Откуда: Sergiev Posad

Сообщение HandKot » 03.04.2008 (Чт) 7:24

и не забыть в хранимой процедуре в начале написать
SET NOCOUNT ON
иначе рекордсет будет всегда заткрыт (точнее там вроде служебнпя информация), и чтобы получить результат выполнения надо будет делать NextRecordset
I Have Nine Lives You Have One Only
THINK!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 03.04.2008 (Чт) 9:51

Antonariy писал(а):Konst_One
p.Append - лишние. Если указать тип adCmdStoredProc, имя и соединение, то параметры создадутся сами - в хранимке они описаны.

Лучше все-же после задания соединения и указания имени вызвать .Refresh, чтобы они гарантированно взялись с базы.
Lasciate ogni speranza, voi ch'entrate.

Altair
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.04.2008 (Ср) 13:02

Сообщение Altair » 03.04.2008 (Чт) 9:56

Не помогло, рекордсет закрыт. В процедуре прописал SET NOCOUNT ON. Процедура собирает данные во временную таблицу, последней строкой в ней идет

select * from #TempTable, остальной код:

Set conn = New ADODB.Connection
Set Command = New ADODB.Command
Set ResRecord = New ADODB.Recordset
ResRecord.CursorLocation = adUseClient

conn.ConnectionString = f_ConnectionString()
conn.Open

'обработка ошибок
On Error GoTo ErrLine

Command.ActiveConnection = conn
Command.CommandType = adCmdStoredProc
Command.CommandText = "GRS_REPORT1_PF"
Command.CommandTimeout = 100

Call Command.Parameters.Append(Command.CreateParameter("RETURN_VALUE", adInteger, adParamReturnValue))

Call Command.Parameters.Append(Command.CreateParameter("@DateEnd", adVarWChar, adParamInput, 20))

Command.Parameters("@DateEnd").Value = ToDate

Call ResRecord.Open(Command, , ADODB.adOpenStatic, adLockReadOnly)


'проверяем наличие данных

If (ResRecord.EOF And ResRecord.BOF) Then
MsgBox ("Нет данных")
GoTo Exitsub
Else

Есть ли еще какие то нюансы?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 03.04.2008 (Чт) 10:00

Код процедуры в студию.
Лучший способ понять что-то самому — объяснить это другому.

Altair
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.04.2008 (Ср) 13:02

Сообщение Altair » 03.04.2008 (Чт) 14:54

Процедура достаточно большая чтобы приводить ее код.
Внутри процедуры есть вызов другой процедуры. После того как убрал этот вызов, проблема с рекордсетом пропала.
Во второй процедуре ошибок нет, в SQL Server все корректно
работает.

Какая для VBA разница вызываю я что-то внутри процедуры или нет?

Altair
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.04.2008 (Ср) 13:02

Сообщение Altair » 03.04.2008 (Чт) 15:35

Во второй процедуре стояло set nocount off,
исправил на on и все заработало.

Спасибо всем


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 248

    TopList