Главная страница
    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.49 MB
Время: 0.037 c
4-1098620405
Пётр Семёнович
2004-10-24 16:20
2004.12.05
Выполнение поставленной ТЗ задачи


14-1100421865
[NIKEL]
2004-11-14 11:44
2004.12.05
Всем привет в армии все нормально! Можете спать спокойно!


1-1101193609
VAV
2004-11-23 10:06
2004.12.05
Значение Property в Классе


1-1101283428
fisherman
2004-11-24 11:03
2004.12.05
Исключительная ситуация


1-1100706304
Apophis
2004-11-17 18:45
2004.12.05
PageControl на Form1 + Form2 на TabSheet...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский