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

Вниз

SQL выражение в ADO вызывает исключение в msvcrt.dll   Найти похожие ветки 

 
oxffff ©   (2007-11-19 09:59) [0]

Добрый день.

Кто нибудь встречался с такой ситуацией.
Имеется TADOQuery и следующий запрос

select value,
 (select count(*) from SourceTrains B join SourceVagons C
  on  B.TrainID=C.TrainID
  where convert(char(10),B.Traindate,2)=A.value
 ) as "Total",
 (select count(*) from SourceTrains B join SourceVagons C
  on B.TrainID=C.TrainID
  where convert(char(10),B.Traindate,2)=A.value and    
               convert(char(2),B.Traindate,8)>=0 and
               convert(char(2),B.Traindate,8)<6                                    
   ) as "0-6 Total",

  ..............
   from (select convert(char(10),Traindate,2) as value
            from SourceTrains  group by convert(char(10),Traindate,2)
          ) A
  where trainId=:param1

После того как делаем

AdoQuery.SQL.add(Это SQL выражение )
вызывает исключение в msvcrt.dll

Самое интересное что если обрамить в скобки(даже в одну скобку выражение FROM,  т.е.

(

from (select convert(char(10),Traindate,2) as value
            from SourceTrains  group by convert(char(10),Traindate,2)
          ) A
  where trainId=:param1

)    <-  эту скобку можно даже не ставить.

то исключение не генерируется.
Но само SQL выражение не корректно.

Что это за баг? и Как его обойти


 
ЮЮ ©   (2007-11-19 10:06) [1]

> AdoQuery.SQL.add(Это SQL выражение )


Если > Это SQL выражение полность сформировано, то зачем Add, а не просто AdoQuery.SQL.Text :=

При AdoQuery.SQL.Add следует обрамлять в AdoQuery.SQL.BeginUpdate ... AdoQuery.SQL.EndUpdate


 
Kolan ©   (2007-11-19 10:07) [2]

> Что это за баг? и Как его обойти

ХЗ, попробовать TADOCommand?


 
oxffff ©   (2007-11-19 10:12) [3]


> ЮЮ ©   (19.11.07 10:06) [1]
> > AdoQuery.SQL.add(Это SQL выражение )
>
>
> Если > Это SQL выражение полность сформировано, то зачем
> Add, а не просто AdoQuery.SQL.Text :=
>
> При AdoQuery.SQL.Add следует обрамлять в AdoQuery.SQL.BeginUpdate
> ... AdoQuery.SQL.EndUpdate


BeginUpdate и EndUpdate не помогают. :(


 
oxffff ©   (2007-11-19 10:13) [4]


> ЮЮ ©   (19.11.07 10:06) [1]
> > AdoQuery.SQL.add(Это SQL выражение )
>
>
> Если > Это SQL выражение полность сформировано, то зачем
> Add, а не просто AdoQuery.SQL.Text :=
>
> При AdoQuery.SQL.Add следует обрамлять в AdoQuery.SQL.BeginUpdate
> ... AdoQuery.SQL.EndUpdate


BeginUpdate is called automatically by any property or method that changes the list of strings.


 
oxffff ©   (2007-11-19 10:14) [5]


> Kolan ©   (19.11.07 10:07) [2]
> > Что это за баг? и Как его обойти
>
> ХЗ, попробовать TADOCommand?


Чисто технически, я думаю результат будет тот же.
Я конечно знаю как обойти. Не использовать параметры вообще. :)


 
oxffff ©   (2007-11-19 10:16) [6]

Самое интересное, что количество выбираемых полей влияет на появление этой ошибки.
это баг. IMHO.


 
Sergey13 ©   (2007-11-19 10:16) [7]

> [0] oxffff ©   (19.11.07 09:59)

А запрос вообще, того, работоспособный?


 
Anatoly Podgoretsky ©   (2007-11-19 10:16) [8]


> AdoQuery.SQL.add(Это SQL выражение )
> вызывает исключение в msvcrt.dll

Это строка, которая вызывает исключение? По крайней мере так выходит из контекста.
Брось ты этот костыль AdoQuery и никогда ничего кроме TAdoDataset и TAdoCommand более не используй.


 
oxffff ©   (2007-11-19 10:22) [9]


> Sergey13 ©   (19.11.07 10:16) [7]


Запрос работоспособный.
Ошибка появляется при анализе параметров.


> Anatoly Podgoretsky ©   (19.11.07 10:16) [8]
>
> > AdoQuery.SQL.add(Это SQL выражение )
> > вызывает исключение в msvcrt.dll
>
> Это строка, которая вызывает исключение? По крайней мере
> так выходит из контекста.
> Брось ты этот костыль AdoQuery и никогда ничего кроме TAdoDataset
> и TAdoCommand более не используй.


Хорошо попробую. Тем более что уже выше рекомендовали.


 
oxffff ©   (2007-11-19 10:26) [10]


> Anatoly Podgoretsky ©   (19.11.07 10:16) [8]


> Kolan ©   (19.11.07 10:07) [2]


Результат тот же

var a:TADODataSet;
begin
a:=TADODataSet.Create(nil);
a.Connection:=ADOConnection;
a.CommandText:= Это SQL выражение

Exception в msvcrt.dll


 
Anatoly Podgoretsky ©   (2007-11-19 10:32) [11]


> Хорошо попробую. Тем более что уже выше рекомендовали.

У некоторых уже мозоли на языке.


 
oxffff ©   (2007-11-19 10:40) [12]


> Anatoly Podgoretsky ©   (19.11.07 10:32) [11]


Однако не помогло.


 
Anatoly Podgoretsky ©   (2007-11-19 10:41) [13]


> a.CommandText:= Это SQL выражение

Вот это уже странно, и это видимо глюк (может немного порушена) в системе. Не должно это вызывать исключения.
Попробуй отладить по шагам
procedure TADOCommand.AssignCommandText(const Value: WideString; Loading: Boolean);

 procedure InitParameters;
 var
   I: Integer;
   List: TParameters;
   NativeCommand: string;
 begin
   List := TParameters.Create(Self, TParameter);
   try
     NativeCommand := List.ParseSQL(Value, True);
     { Preserve existing values }
     List.AssignValues(Parameters);
     CommandObject.CommandText := NativeCommand;
     if not Loading and (Assigned(Connection) or (ConnectionString <> "")) then
     begin
       try
         SetConnectionFlag(cfParameters, True);
         try
           { Retrieve additional parameter info from the server if supported }
           Parameters.InternalRefresh;
           { Use additional parameter info from server to initialize our list }
           if Parameters.Count = List.Count then
             for I := 0 to List.Count - 1 do
             begin
               List[I].DataType := Parameters[I].DataType;
               List[I].Size := Parameters[I].Size;
               List[I].NumericScale := Parameters[I].NumericScale;
               List[I].Precision := Parameters[I].Precision;
               List[I].Direction := Parameters[I].Direction;
               List[I].Attributes := Parameters[I].Attributes;
             end
         finally
           SetConnectionFlag(cfParameters, False);
         end;
       except
         { Ignore error if server cannot provide parameter info }
       end;
       if List.Count > 0 then
         Parameters.Assign(List);
     end;
   finally
     List.Free;
   end;
 end;

begin
 if (CommandType = cmdText) and (Value <> "") and ParamCheck then
   InitParameters
 else
 begin
   CommandObject.CommandText := Value;
   if not Loading then Parameters.Clear;
 end;
end;

Для начала отключи это

> ParamCheck


 
ЮЮ ©   (2007-11-19 10:41) [14]

> a.CommandText:= Это SQL выражение
>
> Exception в msvcrt.dll


> BeginUpdate is called automatically by any property or method
> that changes the list of strings.


Это если бы ты менял сво-во SQL. А ты его не меняешь, а вызываешь методы, его изменяющие. Даже, если SQL.Add автоматически и вызовет BeginUpdate, то так же автоматически вызовет и EndUpdate, что позволит приступить к анвлизу незавершенного текста запрома.  
Тогда и дальше прочти:

Call BeginUpdate before directly modifying the strings in the list, and EndUpdate after. When implementing properties or methods that change the list in descendants of TStrings, call BeginUpdate before the changes are made, and EndUpdate when the changes are complete.


> Запрос работоспособный.

Где проверял?


> Ошибка появляется при анализе параметров.

А кто-бы сомневался? А кроме единственного упоминания :param1 есть ещё параметры


>  ..............
>   from

А может ошибка в ......... ? Закомментируй для начала все поля кроме value /*  */ и добавляй постепенно


 
Sergey13 ©   (2007-11-19 10:42) [15]

> [10] oxffff ©   (19.11.07 10:26)

А Делфи какая? Там вроде до 6 АДО патчить надо. Хотя могу и заблуждаться, с АДО не работаю.


 
ЮЮ ©   (2007-11-19 10:47) [16]

>
> А Делфи какая?


Заодно: А БД какая?


 
Johnmen ©   (2007-11-19 10:53) [17]


> oxffff ©

Есть такой баг в АДО. Если параметр(ы) "запрятаны" глубоко в конструкции SQL выражения. Анализатор не справляется с разбором из-за существующей "вложенности".


 
oxffff ©   (2007-11-19 10:55) [18]


> ЮЮ ©   (19.11.07 10:41) [14]


Проверял в SQL Server Managament Studio 2005.
Сервер MSSQL 2005 standart Edition.

Все поля в .....

Аналог

(select count(*) from SourceTrains B join SourceVagons C
 on  B.TrainID=C.TrainID
 where convert(char(10),B.Traindate,2)=A.value
) as "Total",

Я выше упомянул о том, что если количество полей небольшое, то ошибки нет. А если все поля (которые мне нужны), то валится Exception.

В данном запросе один параметр.

Delphi 7.


 
oxffff ©   (2007-11-19 10:57) [19]


> Johnmen ©   (19.11.07 10:53) [17]


Здесь параметр во внешнем запросе.
Во внутренних подзапросах его нет.

:)

Может и такой баг тоже есть? :)


 
sniknik ©   (2007-11-19 11:01) [20]

> Есть такой баг в АДО. Если параметр(ы) "запрятаны" глубоко в конструкции SQL выражения.
> Анализатор не справляется с разбором из-за существующей "вложенности".
это не глюк ADO, это глюк провайдера, т.к. на разбор выражение предоставляется ему. (и изза чего был таки "глюк ADO",  а вернее TADOQuery, в первых версиях, ошибка добавления в d Add части выражения...)

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


 
oxffff ©   (2007-11-19 11:03) [21]


> Anatoly Podgoretsky ©   (19.11.07 10:41) [13]


Валится на

{ Retrieve additional parameter info from the server if supported }
Parameters.InternalRefresh;


 
oxffff ©   (2007-11-19 11:06) [22]

Валится на  вызове  метода Prepare интерфейса ICommandPrepare


 
Johnmen ©   (2007-11-19 11:07) [23]


> это не глюк ADO, это глюк провайдера,

Т.е. глюк OLEDB драйвера?
Пусть так. Всё равно белкин виноват...:)
Кстати, какой провайдер у автора пока не ясно.


 
Johnmen ©   (2007-11-19 11:08) [24]


> oxffff ©   (19.11.07 11:06) [22]
> Валится на  вызове  метода Prepare интерфейса ICommandPrepare

Что и говорит о кривом анализаторе(разборщике).


 
oxffff ©   (2007-11-19 11:09) [25]


> Johnmen ©   (19.11.07 11:07) [23]


Provider=SQLOLEDB.1;


 
oxffff ©   (2007-11-19 11:09) [26]


> Johnmen ©   (19.11.07 11:07) [23]


Provider=SQLOLEDB.1;


 
Anatoly Podgoretsky ©   (2007-11-19 11:11) [27]

Ты попробовал запретить ParamCheck? Ведь надо сокращать пути поиска проблемы.
Во всяком случае это проблема не АДО, а ниже


 
oxffff ©   (2007-11-19 11:11) [28]


> Johnmen ©   (19.11.07 11:08) [24]


Это то я понимаю. :)
Куда написать, чтобы поправили?


 
sniknik ©   (2007-11-19 11:12) [29]

> Пусть так. Всё равно белкин виноват...:)
не. имхо, автор запроса ;), ибо нефиг слишком сложно и с перекрестными ссылками запросы составлять... нужно себя ограничивать. (а вот то что ошибка непонятная тут да "белкин", могли бы и понятно выдать типа "кончились ресурсы на уровни вложенности" и т.д.)

> Кстати, какой провайдер у автора пока не ясно.
"родной" mssql, сказал.


 
sniknik ©   (2007-11-19 11:12) [30]

> Куда написать, чтобы поправили?
в мелкософт.


 
sniknik ©   (2007-11-19 11:14) [31]

> Ты попробовал запретить ParamCheck?
если получится то параметр можно и самому создать...


 
sniknik ©   (2007-11-19 11:14) [32]

Удалено модератором
Примечание: дубль


 
oxffff ©   (2007-11-19 11:21) [33]


> Anatoly Podgoretsky ©   (19.11.07 11:11) [27]
> Ты попробовал запретить ParamCheck? Ведь надо сокращать
> пути поиска проблемы.
> Во всяком случае это проблема не АДО, а ниже


так помогло

a.ParamCheck:=false;
a.CommandText:=a.Parameters.ParseSQL(SQL,true);
a.Parameters.ParseSQL(SQL,true);
...
a.Parameters.ParamByName("param1").Value:=....
a.Open;


 
oxffff ©   (2007-11-19 11:23) [34]


> sniknik ©   (19.11.07 11:14) [31]
> > Ты попробовал запретить ParamCheck?
> если получится то параметр можно и самому создать...


Можно и ADO самому написать. ;)


 
Сусл ©   (2007-11-19 11:26) [35]

не в тему, зато личный опыт.
я вообще не пользуюсь параметрами - сообираешь полный запрос и дело с концом. также и out параметры процедур возврщаю - в переменные в скрипте, потому select @localvar.

имхо так намного прозрачней, ибо не все там гладко с параметрами - иногда бывают глюки, на которые я прость забил в свое время и начал пользоваться вышеобозначенной методой.


 
Anatoly Podgoretsky ©   (2007-11-19 11:32) [36]

> oxffff  (19.11.2007 11:21:33)  [33]

> a.ParamCheck:=false;
>>>>a.CommandText:=a.Parameters.ParseSQL(SQL,true);
>a.Parameters.ParseSQL(SQL,true);

Наверно описался? a.CommandText := текст_запроса

Ну и работай в данном виде, больше гарантии что движок тебя поймет, не только АДО


 
Anatoly Podgoretsky ©   (2007-11-19 11:33) [37]

> Сусл  (19.11.2007 11:26:35)  [35]

И выяснеешь у сервера, а в каком виде он например принимает даты.
Про оптимизацию я вообще молчу, про нее можешь забыть.


 
sniknik ©   (2007-11-19 11:40) [38]

> Можно и ADO самому написать. ;)
можно, но параметр гораздо проще...
твои действия в [33] как раз один вариантов сделать параметр самому, имхо не самый эффективный, CreateParameter гораздо лучше, и писать меньше.

хотя, писать ты видимо любишь... я бы, вместо всего, постарался бы представить запрос в [0] в меньшем количестве букв, и не таким запутанным.


 
oxffff ©   (2007-11-19 12:20) [39]


> Anatoly Podgoretsky ©   (19.11.07 11:32) [36]
> > oxffff  (19.11.2007 11:21:33)  [33]
>
> > a.ParamCheck:=false;
> >>>>a.CommandText:=a.Parameters.ParseSQL(SQL,true);
> >a.Parameters.ParseSQL(SQL,true);
>
> Наверно описался? a.CommandText := текст_запроса
>
> Ну и работай в данном виде, больше гарантии что движок тебя
> поймет, не только АДО


Нет именно.

a.ParamCheck:=false;
a.CommandText:=a.Parameters.ParseSQL(текст_запроса,true)
a.Parameters.ParseSQL(текст_запроса,true);


 
ЮЮ ©   (2007-11-19 12:24) [40]

> Нет именно.
>
> a.ParamCheck:=false;
> a.CommandText:=a.Parameters.ParseSQL(текст_запроса,true)
>
> a.Parameters.ParseSQL(текст_запроса,true);


Тогда третья строка, пожалуй, лишняя - ведь всё это уже выполнено во аторой.



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

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

Наверх




Память: 0.58 MB
Время: 0.009 c
2-1205908465
zorik
2008-03-19 09:34
2008.04.13
Доступ класса к главному класса и к его свойствам


15-1204254610
Slider007
2008-02-29 06:10
2008.04.13
С днем рождения ! 29 февраля 2008 пятница


4-1186810295
Кирилл_А
2007-08-11 09:31
2008.04.13
bsToolWindow для WinApi


4-1186600664
cerber
2007-08-08 23:17
2008.04.13
запуск документа ворд из ресурса.


15-1204167411
Slider007
2008-02-28 05:56
2008.04.13
С днем рождения ! 28 февраля 2008 четверг





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский