Странное поведение MS SQL Server
От: Zar Россия  
Дата: 25.10.02 09:59
Оценка:
Привет всем.
Столкнулся со транным поведение MS SQL Server. Что делаю: создаю процедуру, которая возвращает один рекордсет, и открываю его ADODB::Recordset-ом из Visual C++ 6.
Так вот, если процедура имеет такой вид:

CREATE PROCEDURE Temp
AS
SELECT * FROM Users

то всё происзодит нормально.
Если же процедура имеет вид:
CREATE PROCEDURE Temp
AS
SELECT * INTO #t FROM Users
SELECT * FROM #t
DROP TABLE #t

то по какой-то причине получившийся рекордсет имеет первый набор записей пустой, у него rs->State = adStateClosed. После того, как я делаю
rs2=rs->NextRecordSet(NULL), я получаю доступ к данным.

Собственно говоря вопро вот в чём: кто-нибудь с этим встречался? И если да, то мож кто знает, как избежать подобного поведения MS SQL сервера? Буду благодарен за любые предложения.
[ Zarathustra ]
Re: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 10:07
Оценка: 8 (1)
Здравствуйте Zar, Вы писали:

Zar>Собственно говоря вопро вот в чём: кто-нибудь с этим встречался? И если да, то мож кто знает, как избежать подобного поведения MS SQL сервера? Буду благодарен за любые предложения.


Это известная фича. Ты получешь счетчик обработанных записей с первого селекта в первом рекордсете.
Поставь в начале процедуры: SET NOCOUNT ON
Re[2]: Странное поведение MS SQL Server
От: Zar Россия  
Дата: 25.10.02 11:07
Оценка:
Здравствуйте Lexey, Вы писали:

L>Здравствуйте Zar, Вы писали:


Zar>>Собственно говоря вопро вот в чём: кто-нибудь с этим встречался? И если да, то мож кто знает, как избежать подобного поведения MS SQL сервера? Буду благодарен за любые предложения.


L>Это известная фича. Ты получешь счетчик обработанных записей с первого селекта в первом рекордсете.

L>Поставь в начале процедуры: SET NOCOUNT ON

Спасиба!
[ Zarathustra ]
Re[2]: Странное поведение MS SQL Server
От: Алекс Россия http://wise-orm.com
Дата: 25.10.02 11:31
Оценка:
Здравствуйте Lexey, Вы писали:

хъ

L>Это известная фича. Ты получешь счетчик обработанных записей с первого селекта в первом рекордсете.

L>Поставь в начале процедуры: SET NOCOUNT ON

ИМХО ты не прав. Хранимаю процедура в MS SQL может возвращать несколько рекордсетов за раз. Здесь именно такой случай. Возвращается два рекордсета, однако первый на момент fetch'а указывает на удаленную таблу, поэтому он не может быть открыт. Со вторым все нормально.
Re[3]: Странное поведение MS SQL Server
От: Zar Россия  
Дата: 25.10.02 11:38
Оценка:
Здравствуйте Алекс, Вы писали:

А>Здравствуйте Lexey, Вы писали:


А>хъ


L>>Это известная фича. Ты получешь счетчик обработанных записей с первого селекта в первом рекордсете.

L>>Поставь в начале процедуры: SET NOCOUNT ON

А>ИМХО ты не прав. Хранимаю процедура в MS SQL может возвращать несколько рекордсетов за раз. Здесь именно такой случай. Возвращается два рекордсета, однако первый на момент fetch'а указывает на удаленную таблу, поэтому он не может быть открыт. Со вторым все нормально.


Хм... А почему же тогда SET NOCOUNT ON помогает? Если первый рекордсет — действительно удалённая таблица #t, то по идее не должно помагать...
[ Zarathustra ]
Re[3]: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 11:41
Оценка:
Здравствуйте Алекс, Вы писали:

А>ИМХО ты не прав. Хранимаю процедура в MS SQL может возвращать несколько рекордсетов за раз.


Проверь, если не веришь. Насчет рекордсетов можешь мне не объяснять, это я и так знаю.

>Здесь именно такой случай. Возвращается два рекордсета, однако первый на момент fetch'а указывает на удаленную таблу, поэтому он не может быть открыт. Со вторым все нормально.


Посмотри внимательно на sql-batch.
Первый стейтмент никакого рекордсета не возвращает. Зато он возвращает счетчик вставленных строк.
Второй стейтмент возвращает записи из таблицы. То, что эту таблицу потом грохают, никого не волнует.
Re[4]: Странное поведение MS SQL Server
От: Алекс Россия http://wise-orm.com
Дата: 25.10.02 11:52
Оценка:
Здравствуйте Lexey, Вы писали:

хъ

L>Посмотри внимательно на sql-batch.

L>Первый стейтмент никакого рекордсета не возвращает. Зато он возвращает счетчик вставленных строк.

Он возвращает пустой рекордсет.

Почеve тогда обыкновенный

create proc aaa as select * from aaa_tbl


Возвращает один рекордсет, хотя информация о кол-ве выбранных строк тоже имеется?
Re[5]: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 12:06
Оценка:
Здравствуйте Алекс, Вы писали:

L>>Посмотри внимательно на sql-batch.

L>>Первый стейтмент никакого рекордсета не возвращает. Зато он возвращает счетчик вставленных строк.

А>Он возвращает пустой рекордсет.


Ну хватит гнать пургу. Возми QA да посмотри.

А>Почеve тогда обыкновенный


А>
А>create proc aaa as select * from aaa_tbl
А>


А>Возвращает один рекордсет, хотя информация о кол-ве выбранных строк тоже имеется?


Потому что информация о числе строк идет после рекордсета.

Процедура возвратит 2 резалтсета (если не стоит nocount on):
1) собственно рекордсет
2) число выбранных записей.
Re[6]: Странное поведение MS SQL Server
От: Алекс Россия http://wise-orm.com
Дата: 25.10.02 12:11
Оценка:
Здравствуйте Lexey, Вы писали:

хъ

L>Ну хватит гнать пургу. Возми QA да посмотри.


Ссылку пожалуйста!

хъ

L>Потому что информация о числе строк идет после рекордсета.


L>Процедура возвратит 2 резалтсета (если не стоит nocount on):

L>1) собственно рекордсет
L>2) число выбранных записей.

Второй рекордсет у меня пустой. Можешь объяснить почему? (стоит nocount on):

З.Ы. Не нервничай и не оверквоть!
Re[7]: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 12:15
Оценка:
Здравствуйте Алекс, Вы писали:

L>>Ну хватит гнать пургу. Возми QA да посмотри.


А>Ссылку пожалуйста!


На что, на Query Analyzer тебе ссылку дать?

L>>Потому что информация о числе строк идет после рекордсета.


L>>Процедура возвратит 2 резалтсета (если не стоит nocount on):

L>>1) собственно рекордсет
L>>2) число выбранных записей.

А>Второй рекордсет у меня пустой. Можешь объяснить почему? (стоит nocount on):


С nocount on второго рекодсета нет вообще.

А>З.Ы. Не нервничай и не оверквоть!


Я не нервничаю и уж тем более не оверквочу.
Re[8]: Странное поведение MS SQL Server
От: Алекс Россия http://wise-orm.com
Дата: 25.10.02 12:19
Оценка:
Здравствуйте Lexey, Вы писали:

[]

Давай еще раз. Ты утверждаешь

Процедура возвратит 2 резалтсета (если не стоит nocount on):
1) собственно рекордсет
2) число выбранных записей.


Второй рекордсет у меня пустой. Т.е. его вообще нет. Nothing есть такое понятие в VB. Почему?

Код следующий

ALTER proc aa_proc as
set nocount off
select * from fff
Re[9]: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 12:24
Оценка:
Здравствуйте Алекс, Вы писали:

Вот тебе цитата из MSDN.

As long as there are additional results and the Recordset containing the compound statements is not disconnected or marshaled across process boundaries, the NextRecordset method will continue to return Recordset objects. If a row-returning command executes successfully but returns no records, the returned Recordset object will be open but empty. Test for this case by verifying that the BOF and EOF properties are both True. If a non–row-returning command executes successfully, the returned Recordset object will be closed, which you can verify by testing the State property on the Recordset. When there are no more results, recordset will be set to Nothing.

Счетчик как раз попадает в категорию non-row resultset.

А>Давай еще раз. Ты утверждаешь

А>
А>Процедура возвратит 2 резалтсета (если не стоит nocount on):
А>1) собственно рекордсет
А>2) число выбранных записей.
А>


Да. И это так и есть.

А>Второй рекордсет у меня пустой. Т.е. его вообще нет. Nothing есть такое понятие в VB. Почему?


Пустой и вообще нет — совершенно разные вещи. Пустой — это BOF = EOF = TRUE.

А>Код следующий


А>
А>ALTER proc aa_proc as
А>set nocount off
А>select * from fff
А>


У меня ровно такой же код в QA дает 2 резалтсета. Чем ты смотришь?
Re[10]: Странное поведение MS SQL Server
От: Алекс Россия http://wise-orm.com
Дата: 25.10.02 12:31
Оценка:
Здравствуйте Lexey, Вы писали:

L>Здравствуйте Алекс, Вы писали:


[MSDN можешь не цитировать.]

А>>Второй рекордсет у меня пустой. Т.е. его вообще нет. Nothing есть такое понятие в VB. Почему?


L>Пустой и вообще нет — совершенно разные вещи. Пустой — это BOF = EOF = TRUE.


Я же сказал — его нет вообще!

А>>Код следующий


А>>
А>>ALTER proc aa_proc as
А>>set nocount off
А>>select * from fff
А>>


L>У меня ровно такой же код в QA дает 2 резалтсета. Чем ты смотришь?


У меня тоже два результата. Один в виде рекордсета, другой в виде строки. Но на клиенте рекордсет один!

    Dim r As Recordset, r1 As Recordset
    Dim cmd As New Command
    Set cmd.ActiveConnection = c
    cmd.CommandType = adCmdStoredProc
    cmd.CommandText = "aa_proc"
    Set r = cmd.Execute
    Do While Not r.EOF
        Debug.Print r.Fields(0)
        r.MoveNext
    Loop
    Set r1 = r.NextRecordset
    If Not r1 Is Nothing Then
        Do While Not r1.EOF
            Debug.Print r1.Fields(0)
            r1.MoveNext
        Loop
    End If


Если ты хоть чуть-чуть в VB шаришь, попробуй проверь, а после этого будем нулями кидаться.
Re[11]: Странное поведение MS SQL Server
От: Merle Австрия http://rsdn.ru
Дата: 25.10.02 12:57
Оценка:
Здравствуйте Алекс, Вы писали:

Алекс, ты не прав.
Первый рекордсет ни на какую удаленную таблицу указывать не может... Все происходит именнто так как написал Lexey и как написано в MSDN. Тоесть первое выражение есть non–row-returning command и в рекордсете оказывается число строк, второй же рекордсет возвращает нужную нам таблицу. Команда SET NOCOUNT ON подавляет вывод служебной информации, что нам и надо, чтобы лишний раз по рекордсетам не елозить...


Твой же пример вполне себе row-returning...

Try this:

    ALTER proc aa_proc as
    set nocount off
    select * into #tmp from fff



    Dim r As Recordset, r1 As Recordset
    Dim cmd As New Command
    Set cmd.ActiveConnection = c
    cmd.CommandType = adCmdStoredProc
    cmd.CommandText = "aa_proc"
    Set r = cmd.Execute
    Do While Not r.EOF
        Debug.Print r.Fields(0)
        r.MoveNext
    Loop


И доложи о результатах... )
А-то у меня VB под рукой нету...
А>Если ты хоть чуть-чуть в VB шаришь, попробуй проверь, а после этого будем нулями кидаться.
Да, тут ты прав, ноль он тебе не за тот постинг поставил...
Мы уже победили, просто это еще не так заметно...
Re[12]: Странное поведение MS SQL Server
От: Алекс Россия http://wise-orm.com
Дата: 25.10.02 13:05
Оценка:
Здравствуйте Merle, Вы писали:

M>Здравствуйте Алекс, Вы писали:


M>Алекс, ты не прав.

M>Первый рекордсет ни на какую удаленную таблицу указывать не может... Все происходит именнто так как написал Lexey и как написано в MSDN. Тоесть первое выражение есть non–row-returning command и в рекордсете оказывается число строк, второй же рекордсет возвращает нужную нам таблицу.

А-га уже первый рекордсет должен возвращать строку, а второй данные. Вы оба цитируете MSDN, а говорите разные вещи.

хъ

M>
M>    ALTER proc aa_proc as
M>    set nocount off
M>    select * into #tmp from fff
M>


M>

M>
M>    Dim r As Recordset, r1 As Recordset
M>    Dim cmd As New Command
M>    Set cmd.ActiveConnection = c
M>    cmd.CommandType = adCmdStoredProc
M>    cmd.CommandText = "aa_proc"
M>    Set r = cmd.Execute
M>    Do While Not r.EOF
M>        Debug.Print r.Fields(0)
M>        r.MoveNext
M>    Loop
M>


M>И доложи о результатах... )


Докладываю. Как ни странно это звучит, но никакой рекордсет не возвращается. Nothing по VB-ому говоря.

Еще какие мысли есть?
Re[11]: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 13:09
Оценка:
Здравствуйте Алекс, Вы писали:

А>У меня тоже два результата. Один в виде рекордсета, другой в виде строки. Но на клиенте рекордсет один!


Да, тут ты все-таки прав. Я зря разделил счетчик записей и рекордсет — OLE DB возвращает их вместе как один результат. ADO похоже оставляет только одно — либо рекордсет, если он есть, либо счетчик, если рекордсета нет.
QA умеет вытаскивать оба объекта.

А>Если ты хоть чуть-чуть в VB шаришь, попробуй проверь, а после этого будем нулями кидаться.


Ноль за тот пост я убрал, но в остальном ты все равно был не прав.
Re[13]: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 13:14
Оценка:
Здравствуйте Алекс, Вы писали:

M>>Алекс, ты не прав.

M>>Первый рекордсет ни на какую удаленную таблицу указывать не может... Все происходит именнто так как написал Lexey и как написано в MSDN. Тоесть первое выражение есть non–row-returning command и в рекордсете оказывается число строк, второй же рекордсет возвращает нужную нам таблицу.

А>А-га уже первый рекордсет должен возвращать строку, а второй данные. Вы оба цитируете MSDN, а говорите разные вещи.


Ты опять что-то путаешь. Тут мы говорим ровно одно и тоже. По моим словам к этому должен был бы еще добавится третий рекордсет со строкой. Вот его действительно не будет.
Re[12]: Странное поведение MS SQL Server
От: andik  
Дата: 25.10.02 13:20
Оценка:
вся проблема в том, что ADO в Си и на VB
работает по разному

в VB можно "set nocount on" не ставить, там все проглатывается
а вот если в Си, то надо

почему так, в свое время не выяснили, но есть такой трабл, так что моджете не спорить

p.s. Смотрите первое сообщение
Re[12]: Странное поведение MS SQL Server
От: Алекс Россия http://wise-orm.com
Дата: 25.10.02 13:21
Оценка:
Здравствуйте Lexey, Вы писали:

хъ

L>Ноль за тот пост я убрал, но в остальном ты все равно был не прав.


Возможно. На самом деле (извини конечно) я тут тебя немного провоцировал. По другому от гуру ответа не добится.

Я уже задавал вопрос о том, по каким каналам можно получить информацию о кол-ве выбранных строк, как это делает QA. Возможно ли это с помощью ADO или OLEDB. Вот.

И еще. Непонятно как установка nocount помогла в вышеописанном случае.
Re[13]: Странное поведение MS SQL Server
От: Lexey Россия  
Дата: 25.10.02 13:26
Оценка:
Здравствуйте Алекс, Вы писали:

L>>Ноль за тот пост я убрал, но в остальном ты все равно был не прав.


А>Возможно. На самом деле (извини конечно) я тут тебя немного провоцировал. По другому от гуру ответа не добится.


Мда, проворакатор.

А>Я уже задавал вопрос о том, по каким каналам можно получить информацию о кол-ве выбранных строк, как это делает QA. Возможно ли это с помощью ADO или OLEDB. Вот.


Ну в общем-то, в OLE DB это описано в описании IMultipleResults.

А>И еще. Непонятно как установка nocount помогла в вышеописанном случае.


Да как раз все понятно. select .. into — это как раз та самая non-row-returning command. С nocount off она возвращает число обработанных записей, которое и попадает в первый рекордсет. Noucount on подавляет этот возврат.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.