![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
SQL выражение в ADO вызывает исключение в msvcrt.dll
oxffff © (2007-11-19 09:59:00)Добрый день.
Кто нибудь встречался с такой ситуацией.
Имеется 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 выражение не корректно.
Что это за баг? и Как его обойти
oxffff (2007-11-19 13:29:00) [101]
> Anatoly Podgoretsky © (19.11.07 13:13) [47]
А у меня пример из сегодняшнего проекта. :)
Только у меня TadoDataset у которого нет Execute.
+запрос для возврат набора данных.
Anatoly Podgoretsky (2007-11-19 13:13:00) [102]Вот пример из одного очень древнего проекта
CommonCommand.CommandText := 'DELETE FROM AuditDocuments WHERE OperationTime<:D';
CommonCommand.Parameters.ParseSQL(CommonCommand.CommandText, True);
CommonCommand.Parameters.ParamByName('D').Value := Now - 30;
CommonCommand.Execute;
ParamCheck = False
Сусл (2007-11-19 12:54:00) [103]
> [37] Anatoly Podgoretsky © (19.11.07 11:33)
> > Сусл (19.11.2007 11:26:35) [35]
>
> И выяснеешь у сервера, а в каком виде он например принимает
> даты.
> Про оптимизацию я вообще молчу, про нее можешь забыть.
грусновато, Анатолий, от тебя это слышать.
1. конкретный сервер всегда имеет универсальный формат даты, которые понимается всегда. есть он и у mssql.
2. ты смотрел профайлером как вызывается например AdoCommand? Это приводит к вызову sp_executesql. никто мне не запрещает пользоваться его параметрами самому. оптимизация (я так понимаю повторное использование плана запроса) в этом случае будет работать прекрасно.
а для оптимизации существенно важднее при использовании sp_executesql не забывать давать fully qualified всем таблицами и запросам (документированная, кстати, фича).
oxffff (2007-11-19 12:40:00) [104]
> Кроме этого можно параметр создать и в ДизайнТайм, для фиксированых
> запросов.
В том то и дело, что запросы у меня формируются на лету.
И количество параметров меняется в зависимости от условий.
Генератор запроса сам ищет нужный параметр в классе формы и заполняет его на лету.
Таким образом я здесь вообще не принимаю участия, за исключением написания этой логики.
oxffff (2007-11-19 12:36:00) [105]
> Anatoly Podgoretsky © (19.11.07 12:27) [43]
Если сделать, на чем настаиваете вы, а именно
a.CommandText:=текст_запроса
a.Parameters.ParseSQL(текст_запроса,true);
..
a.open;
тогда ошибка следующая
Incorrect systax near :
при Adodataset.open
Anatoly Podgoretsky (2007-11-19 12:27:00) [106]> oxffff (19.11.2007 12:20:39) [39]
Это странное слово - собака друг человека.
В данной строке должен быть запрос, а вот следующая строка как раз и занимается парсингом и созданием параметров, и то иногда не сможет исправиться. Кроме этого можно параметр создать и в ДизайнТайм, для фиксированых запросов.
oxffff (2007-11-19 12:26:00) [107]
> ЮЮ © (19.11.07 12:24) [40]
После второй строки a.Parameters.Count=0.
ЮЮ (2007-11-19 12:25:00) [108]> Тогда третья строка, пожалуй, лишняя - ведь всё это уже
> выполнено во аторой.
Мда, поспешил.a.CommandText:=очистит a.Parameters
ЮЮ (2007-11-19 12:24:00) [109]> Нет именно.
>
> a.ParamCheck:=false;
> a.CommandText:=a.Parameters.ParseSQL(текст_запроса,true)
>
> a.Parameters.ParseSQL(текст_запроса,true);
Тогда третья строка, пожалуй, лишняя - ведь всё это уже выполнено во аторой.
oxffff (2007-11-19 12:20:00) [110]
> 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);
sniknik (2007-11-19 11:40:00) [111]> Можно и ADO самому написать. ;)
можно, но параметр гораздо проще...
твои действия в [33] как раз один вариантов сделать параметр самому, имхо не самый эффективный, CreateParameter гораздо лучше, и писать меньше.
хотя, писать ты видимо любишь... я бы, вместо всего, постарался бы представить запрос в [0] в меньшем количестве букв, и не таким запутанным.
Anatoly Podgoretsky (2007-11-19 11:33:00) [112]> Сусл (19.11.2007 11:26:35) [35]
И выяснеешь у сервера, а в каком виде он например принимает даты.
Про оптимизацию я вообще молчу, про нее можешь забыть.
Anatoly Podgoretsky (2007-11-19 11:32:00) [113]> 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 := текст_запроса
Ну и работай в данном виде, больше гарантии что движок тебя поймет, не только АДО
Сусл (2007-11-19 11:26:00) [114]не в тему, зато личный опыт.
я вообще не пользуюсь параметрами - сообираешь полный запрос и дело с концом. также и out параметры процедур возврщаю - в переменные в скрипте, потому select @localvar.
имхо так намного прозрачней, ибо не все там гладко с параметрами - иногда бывают глюки, на которые я прость забил в свое время и начал пользоваться вышеобозначенной методой.
oxffff (2007-11-19 11:23:00) [115]
> sniknik © (19.11.07 11:14) [31]
> > Ты попробовал запретить ParamCheck?
> если получится то параметр можно и самому создать...
Можно и ADO самому написать. ;)
oxffff (2007-11-19 11:21:00) [116]
> 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;
sniknik (2007-11-19 11:14:00) [117]> Ты попробовал запретить ParamCheck?
если получится то параметр можно и самому создать...
sniknik (2007-11-19 11:14:00) [118]Удалено модератором
Примечание: дубль
sniknik (2007-11-19 11:12:00) [119]> Пусть так. Всё равно белкин виноват...:)
не. имхо, автор запроса ;), ибо нефиг слишком сложно и с перекрестными ссылками запросы составлять... нужно себя ограничивать. (а вот то что ошибка непонятная тут да "белкин", могли бы и понятно выдать типа "кончились ресурсы на уровни вложенности" и т.д.)
> Кстати, какой провайдер у автора пока не ясно.
"родной" mssql, сказал.
sniknik (2007-11-19 11:12:00) [120]> Куда написать, чтобы поправили?
в мелкософт.