![]() |
| ||
|
|
Новости |
Поиск |
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 17:03:00) [61]
> Anatoly Podgoretsky © (19.11.07 16:59) [85]
Во первых я не жалуюсь.
А во вторых, если я и говорю об этом. То все это были действительно баги, о которых я написал в QC.
За исключеним одного случая, где было выравнивание в стеке по границе DWORD. Но Сергей М. меня поправил. Я правда об этом не знал.
В чем и признался.
А все остальное были баги.
Так что будьте более внимательны.
Anatoly Podgoretsky (2007-11-19 17:03:00) [62]> oxffff (19.11.2007 16:59:26) [86]
Может и пытался, хотя обычно обхожу стороной подобные ветки. Эта просто меня заинтересовала, решил проверить на разных версиях. А применять подобное никогда не буду. Конечно грабли это бесченный опыт, но можно и без него.
А ты что решил наехать? Так зря, я как то безраличен.
Anatoly Podgoretsky (2007-11-19 16:59:00) [63]> oxffff (19.11.2007 16:56:24) [84]
Ну не буду же я извлекать все сообщения из форумов, это мое наблюдение, ты часто жалуешься, что обнаружил баг, и потом идет разборка баг или нет. Неужели я тебя с кем то перепутал?
oxffff (2007-11-19 16:59:00) [64]Anatoly Podgoretsky © (19.11.07 16:43) [83]
Знаете а у меня кстати сложилось обратное впечатление,
где вы и господин sniknik © пытались убедить меня в том, что нарушение семантики типа и правил языка - это нормально.
oxffff (2007-11-19 16:56:00) [65]
> Anatoly Podgoretsky © (19.11.07 16:43) [83]
Пожалуйста тыкните меня носом в то место, где мое представление о работе компилятора не совпадает, а то знаете не хорошо так.
Anatoly Podgoretsky (2007-11-19 16:43:00) [66]> oxffff (19.11.2007 16:36:22) [82]
Ладно проехали, раз не понял.
Но вот что я наблюдаю, гляда за тобой, ты часто применяешь рискованые вещи, иногда действительно нарываешь на баг, а чаще на то, что твое представление не совпадает с представлением компилятора. Но это твое право.
oxffff (2007-11-19 16:36:00) [67]
> Anatoly Podgoretsky © (19.11.07 16:34) [81]
Что почему?
Anatoly Podgoretsky (2007-11-19 16:34:00) [68]> oxffff (19.11.2007 16:30:20) [80]
Непонятно зачем, ты объясняешь как, а не почему (зачем).
oxffff (2007-11-19 16:30:00) [69]Anatoly Podgoretsky © (19.11.07 16:15) [78]
sniknik © (19.11.07 16:21) [79]
Начнем по порядку.
1. Баг1 не некорректная обработка параметров провайдером.
--> Решение
Dataset.ParamCheck:=false;
Dataset.CommandText:=Dataset.Parameters.ParseSQL(SQL,true);
Dataset.Parameters.ParseSQL(SQL,true);
Но поскольку у меня вместо SQL был вызов процедуры которая возвращает WideString. А поскольку в двух вызовах создается две копии string. Поэтому одна на другую не влияет.
Далее.
Я делаю так
SQL:= <- здесь это уже string
Dataset.ParamCheck:=false;
Dataset.CommandText:=Dataset.Parameters.ParseSQL(SQL,true);
Dataset.Parameters.ParseSQL(SQL,true);
и нарываюсь на другие грабли уже в delphi.
По скольку если строка в куче, то параметров после вызова
Dataset.CommandText:=Dataset.Parameters.ParseSQL(SQL,true);
уже нет.
По скольку они заменены на ? напрямую во входном параметре.
А после вызов Dataset.Parameters.ParseSQL(SQL,true);
не создает параметров. По скольку в строке уже их нет.
Чего не понятно то?
sniknik (2007-11-19 16:21:00) [70]> Теперь понятно??
а вот теперь мне не понятно, получается ты специально "сбил настройки", в полном уме и трезвой памяти, а после удивляешься "ой, а тут получается разный результат", получая этот результат оттуда откуда не должен...
зачем?
Anatoly Podgoretsky (2007-11-19 16:15:00) [71]> oxffff (19.11.2007 16:09:16) [76]
Это то понятно, а вот цель нет.
oxffff (2007-11-19 16:11:00) [72]
> oxffff © (19.11.07 16:09) [76]
А далее идет прямое обращение со строкой приводя ее к pchar, тем самым нарушая семантику типа.
Отсюда грабли.
Теперь понятно??
oxffff (2007-11-19 16:09:00) [73]
> Anatoly Podgoretsky © (19.11.07 15:40) [74]
> > oxffff (19.11.2007 15:36:11) [71]
>
> Я возможно не понимаю истинной цели данной операции.
> Anatoly Podgoretsky © (19.11.07 15:40) [74]
Потому что для строкового литерала(который размещен в сегменте данных будет создана копия при Result := SQL (первая строка ParseSQL)
А для не строкового литерала будет просто увеличен счетчик.
См. реализацию LStrLAsg
Anatoly Podgoretsky (2007-11-19 15:43:00) [74]> Сусл (19.11.2007 15:34:10) [70]
Можно много чего, но я предпочту стандартный механизм. Но если ты обеспечишь изменение запроса, что бы получилось where a=? и сумеешь передать параметры, тогда да, но тогда это ничем не будет отличаться от стандартного пути + некоторый геморой.
А как выполняются запросы в MS SQL неплохо описано в BOL, я попытался рассказать на рабоче-крестьянском. Ведь если я даже и стремлюсь переубедить тебя, то не очень настойчиво.
Anatoly Podgoretsky (2007-11-19 15:40:00) [75]> oxffff (19.11.2007 15:36:11) [71]
Я возможно не понимаю истинной цели данной операции.
oxffff (2007-11-19 15:39:00) [76]oxffff © (19.11.07 15:36) [71]
Точнее
oxffff © (19.11.07 14:16) [53]
oxffff © (19.11.07 14:16) [54]
Anatoly Podgoretsky (2007-11-19 15:39:00) [77]> oxffff (19.11.2007 15:34:09) [69]
Нет, я так не говорил, это не нормально, как ошибка, так и код.
Твое объяснение насчет ссылок меня не убедило.
oxffff (2007-11-19 15:36:00) [78]
> Это баг, но привел к нему ты, кострукцией B := B + Text
Да какая конструкция. Эта конструкция нужна для того, чтобы выявить бажную ситуацию. И сделано для того, чтобы строка была в куче, а сегменте данных. Я же вам написал
oxffff © (19.11.07 14:13) [53]
oxffff © (19.11.07 14:30) [60]
oxffff (2007-11-19 15:34:00) [79]
> Anatoly Podgoretsky © (19.11.07 15:26) [68]
Что значит я привел?
То есть вы хотите сказать, что это нормально?
А правильно вас понял?
Сусл (2007-11-19 15:34:00) [80]
> [57] Anatoly Podgoretsky © (19.11.07 14:25)
>
> > ты эта, невнимательно мой пост прочел.
>
> Разве нет, если не понял, то доведи свою мысль. Мой ответ
> касается MS SQL и как подготавливаются запросы, если в запросе
> будет изменен хотя бы один символ, то он будет перекомпилирован,
> со статистикой 0 и неизвестным планом.
запрос все равно в большинстве случаев выливается в вызов sp_executesql
так тебе никто не мешает самому пользоваться ентой штукой.
вот о чем речь.