Текущий архив: 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