Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.12.05;
Скачать: CL | DM;

Вниз

Проблемы с ADO и multiple recordsets   Найти похожие ветки 

 
Тимохов ©   (2004-10-31 15:50) [0]

Добрый день.

(Сервер MSSQL server)

Симптомы проблемы
--------------------
Иногда один и тот же запрос возвращает два recordset вместо одного. Причем, второй recordset является требуемым рекордсетом, а первый - закрытый recordset без единого поля.

Подробное описание
--------------------
Имеется (упрощенно, но суть вопроса отражает точно):
1. Процедура SomeProc с параметром Param1, которая возвращает ровно один Recordset.
2. Некий клиентский запрос, который:
  а) Выполняет SomeProc
  б) Полученный рекордсет возвращает как результат предварительно сбросив его во временную таблицу и несколько обработав.

схематически код выглядит так:


create #t (fld1 int, fld2 int)
insert #t (fld1, fld2) exec SomeProc Param1
insert SomeTable select distinct fld1, fld2 from #t
select fld1, fld2 from #t


который я выполняю с использованием AdoDb.Command (связываение раннее). Например так

Cmd := ADODB.CoCommand.Create;
Cmd.Set_CommandText(<текст приведенного выше запроса>);   Cmd.Set_CommandType(adCmdText);
Cmd.Set_CommandTimeout(1000);
Cmd.Set_ActiveConnection(Cnn);
RS := Cmd.Execute(kRecordsAffected, VarArrayOf([...параметры...]), adCmdUnspecified);


При этом по непонятному закону при одном и том же значении параметров иногда оказывается, что RS = пустому закрытому recordset и для того, чтобы получить нужный нужно вызывать RS.NextRecordSet. Природу первого рекорсета я понять не могу. Ниже я объясню, как пытался понять.

Что я делал для того, чтобы решить проблему
---------------------------------------------
1) Сразу возникло подозрение, что в SomeProc (ее писал не я) есть два Select или Compute (согласно MSDN именно эти конструкции генерят несколько recordset). Но при детальном анализе PROFILER"а в режиме просмотра абсолютно всех интструкций (в том числе и внутри процедур) и кода процедры видно, что никакого лишнего select и compute нет.
2) Одно из решений проблемы было такое - взять тело процедуры и полность перенести в скрипт. В этом случае все работает ОК.
3) Всю документацию, которая доступна я уже просмотрел. Везде пишут как делать несколько recordset, но откуда может браться лишний никто не пишет.
4) Накатил mdac 2.8 - ничего не изменилось.

Что я думаю по этому поводу
-----------------------------
У меня есть устойчивое ощущение, что это есть глюк. Глюк ado или сервера в конструкции insert ... exec ...
При том, что ado и sql server"ом я занимаюсь пятый год и свое время прочел все что можно, куда копать я не знаю.

Вопрос
-------
1) Встречался ли кто-нибудь с таким поведением ado при использовании insert ... exec ...?
2) Если это все-же тянет на глюк, то где в msdn читать о заявленных ошибках (если я не ошибаюсь это должно быть)?

Заранее благодарен.


 
sniknik ©   (2004-10-31 17:26) [1]

из приведенного запроса вернется 4 рекордсета(с установками по дефаулту) только последний с данными, первые пустые только с количеством применненных записей.
если пустые не нужны первой должна быть команда SET NOCOUNT ON
кстати твой непонятный закон как раз может быть тем что с этой командой безалаберно обращаются ;о) (гдето в другом месте до твоего включают/отключают), и у тебя все зависит после чего это вызвано.


 
Тимохов ©   (2004-10-31 17:40) [2]


>  [1] sniknik ©   (31.10.04 17:26)

Ну началось... :)
Почти месяц не было меня на форуме, подзабыл дух издевки:)))

По делу.


> если пустые не нужны первой должна быть команда SET NOCOUNT ON

Это не оказывает влияния :)) Пробовал уже.

Я попробовал 342 варианта решения (из нормальных). Кто больше?

Повторю, что решение с заменой inset ... exec на insert ... select с выносом кода процедуры в мой запрос (и, конечно, удалением процедуры) работает правильно.


 
sniknik ©   (2004-10-31 17:51) [3]

где издевка? вполне серьезно.

> Это не оказывает влияния :)) Пробовал уже.
а в процедуре твоей смотрел? может там вызывается с OFF.

> Повторю, что решение с заменой inset ... exec на insert ... select с выносом кода процедуры в мой запрос (и, конечно, удалением процедуры)
> работает правильно.
ну вот почти подтвердил.

можно обойти, цикл с NextRecordSet организовать, до последнего рекордсета (вернее предпоследнего ;о) последний будет nil), тоже пробовал судя по описанию?


 
Тимохов ©   (2004-10-31 17:57) [4]


>  [3] sniknik ©   (31.10.04 17:51)

Ты читал в после про исползование profiler"a?
Конечно я смотрел и код процедуры и резуьтат работы profiler - я смотрел каждый statment в том числе и внутри процедуры. Заметь, что ошибка происходит не всегда. Один и тот же запрос, то выполнятеся, то нет. Вероятность примерно 1 к 1.


> можно обойти, цикл с NextRecordSet организовать, до последнего
> рекордсета (вернее предпоследнего ;о) последний будет nil),
> тоже пробовал судя по описанию?

И хто я после этого - чмо-ламо? Пока мне ничего не остается, как сделать именно так.


 
Тимохов ©   (2004-10-31 18:10) [5]


> [3] sniknik ©   (31.10.04 17:51)

Проблема состоит именно в том, что решение насущной проблемы я знаю. Но почему получается так?

Не скрою, что у нас (уж извините) просто изнасилованный сервер. Он делает большую долю несвойственной sql серверам работу. Например, он является mapper"ом между объектной моделью в дельфи и реляционными таблицами в себе же. Изначально все это позиционировалось как реляционная надстройка над реляционной базой. В принципе в настоящий момент все именно так и работает - полиформизм и наследование исползуются достаточно активно. В принципе и инкапсуляция есть, но пока не полная.

Но не редки случае, когда некие компоненты сервера (оптимизатор, например) от запросов приходят в ступор. Запрос разбирается 3 минуты, а выполяется 388 мс. Но в таких случая глубокого знания поведения сервера (я имею в виду наших админов) хватает, чтобы с помощью хинтов направить поведение сервера в правильное русло. Часто наши запросы проигрывают чистой реляционке совсем немного.

Но в данном случае, все разводят руками...

Вот и интересуем меня, может у кого-то тоже запученный до потери сознания сервер, который приводит к таким вот глюкам.


 
sniknik ©   (2004-10-31 18:30) [6]

ну не знаю, проверил у себя, никаких неожиданностей  

сначала сделал простую процедуру
CREATE PROCEDURE SomeProc @Param1 integer
AS
SELECT ID, CurrencyID
FROM CurrencyRate
WHERE CurrencyID=@Param1


после выполняю твой блок (исправил небольшой глюк, описался? прям сдесь писал?)

create table #t (fld1 int, fld2 int)
insert #t (fld1, fld2) exec SomeProc 1
insert SomeTable select distinct fld1, fld2 from #t
select fld1, fld2 from #t
drop table #t


получаю
Выполнено применительно к 1 записям. (no recordset)
                       применительно к 1 записям. (no recordset)
                       применительно к 1 записям
ничего наожиданного, да?
потом заменил процедуру на
CREATE PROCEDURE SomeProc @Param1 integer
AS

IF @Param1 = 1 SET NOCOUNT ON
ELSE SET NOCOUNT OFF

SELECT ID, CurrencyID
FROM CurrencyRate
WHERE CurrencyID=@Param1


ну так, для проверки
и с еденицей и с двойкой в параметре все одно несколько записей
Выполнено применительно к 6 записям. (no recordset)
                       применительно к 6 записям. (no recordset)
                       применительно к 6 записям

... от NOCOUNT внутри процедуры независит (ошибся я), а вот в начале блока очень даже зависит.
проверь также, на упрощенных данных может что прояснит.


 
Johnmen ©   (2004-11-01 09:15) [7]

>Тимохов ©   (31.10.04 17:40) [2]
>Ну началось... :)
>Почти месяц не было меня на форуме, подзабыл дух издевки:)))

И что ты делал этот месяц, что стал таким нервным и раздражительным ? Может стОит поспокойнее ?


 
Тимохов ©   (2004-11-01 11:25) [8]


>  [7] Johnmen ©   (01.11.04 09:15)

Смайлики видел? :)))


>  [6] sniknik ©   (31.10.04 18:30)

Если ошибку не найду пришлю неработающий пример. Пока с примером проблемы. Составляю его удалением лишнего из нашего сервера. Муторная это работа.


 
Тимохов ©   (2004-11-01 11:27) [9]


>  [7] Johnmen ©   (01.11.04 09:15)

Смайлики видел? :)))


>  [6] sniknik ©   (31.10.04 18:30)

Если ошибку не найду пришлю неработающий пример. Пока с примером проблемы. Составляю его удалением лишнего из нашего сервера. Муторная это работа.


> после выполняю твой блок (исправил небольшой глюк, описался?
> прям сдесь писал?)

Я же сказал, что пример упрошенный, конечно тут писал.


 
Тимохов ©   (2004-11-01 11:42) [10]


> [7] Johnmen ©   (01.11.04 09:15)

Еще раз повторю дабы не тратить время на раздумия - set nocount on!!!

Дошел до маразма - ставил его перед каждой строкой своего скрипта и каждой строкой процедуры :)))

Нету такому поведению нормального объяснения.

А я сошла с ума (с) Фрейкин бок.


 
Суслик ©   (2004-11-04 12:36) [11]

Up.

Может у кого появятся идеи... а может нет :(



Страницы: 1 вся ветка

Текущий архив: 2004.12.05;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.052 c
1-1100950490
Arnold
2004-11-20 14:34
2004.12.05
Ошибка при преобразовании числа


4-1098160932
Sod
2004-10-19 08:42
2004.12.05
смена цвета фона приложения


14-1099305727
Юрий Федоров
2004-11-01 13:42
2004.12.05
Вакансия в москве


3-1099639485
diabolik_krsk
2004-11-05 10:24
2004.12.05
Сохранение данных их ComboBox в Access


3-1099571426
Mih
2004-11-04 15:30
2004.12.05
Вопрос поиска.