Текущий архив: 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);
Тогда третья строка, пожалуй, лишняя - ведь всё это уже выполнено во аторой.
← →
ЮЮ © (2007-11-19 12:25) [41]> Тогда третья строка, пожалуй, лишняя - ведь всё это уже
> выполнено во аторой.
Мда, поспешил.a.CommandText:=
очистит a.Parameters
← →
oxffff © (2007-11-19 12:26) [42]
> ЮЮ © (19.11.07 12:24) [40]
После второй строки a.Parameters.Count=0.
← →
Anatoly Podgoretsky © (2007-11-19 12:27) [43]> oxffff (19.11.2007 12:20:39) [39]
Это странное слово - собака друг человека.
В данной строке должен быть запрос, а вот следующая строка как раз и занимается парсингом и созданием параметров, и то иногда не сможет исправиться. Кроме этого можно параметр создать и в ДизайнТайм, для фиксированых запросов.
← →
oxffff © (2007-11-19 12:36) [44]
> Anatoly Podgoretsky © (19.11.07 12:27) [43]
Если сделать, на чем настаиваете вы, а именно
a.CommandText:=текст_запроса
a.Parameters.ParseSQL(текст_запроса,true);
..
a.open;
тогда ошибка следующая
Incorrect systax near :
при Adodataset.open
← →
oxffff © (2007-11-19 12:40) [45]
> Кроме этого можно параметр создать и в ДизайнТайм, для фиксированых
> запросов.
В том то и дело, что запросы у меня формируются на лету.
И количество параметров меняется в зависимости от условий.
Генератор запроса сам ищет нужный параметр в классе формы и заполняет его на лету.
Таким образом я здесь вообще не принимаю участия, за исключением написания этой логики.
← →
Сусл © (2007-11-19 12:54) [46]
> [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 всем таблицами и запросам (документированная, кстати, фича).
← →
Anatoly Podgoretsky © (2007-11-19 13:13) [47]Вот пример из одного очень древнего проекта
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
← →
oxffff © (2007-11-19 13:29) [48]
> Anatoly Podgoretsky © (19.11.07 13:13) [47]
А у меня пример из сегодняшнего проекта. :)
Только у меня TadoDataset у которого нет Execute.
+запрос для возврат набора данных.
← →
Anatoly Podgoretsky © (2007-11-19 13:30) [49]
> грусновато, Анатолий, от тебя это слышать.
Почему же грустно, это же обусловлено принципом работы сервера
НапримерWHERE DT="20071119"
иWHERE DT="20071120"
Будет проводится полный комплекс от разбора до компиляции запроса, аWHERE DT=:DT
при любых DT как минимум компилирование будет только один раз, но также сработает и статистика, в результате если 19 числа запрос выполнялся за 30 секунд, то 20 возможно уже за 10 секунд.
← →
Anatoly Podgoretsky © (2007-11-19 13:34) [50]> oxffff (19.11.2007 13:29:48) [48]
Не обращай ты внимание на Execute, это первый попавшийся пример. Для dataset тоже самое, только Open
Правда я эту технику использовал только на БДЕ, там эта проблема с параметрами наблюдалась, а на АДО я ни разу не наткнулся. Но я помню эту технологию на случай возникновение проблем.
← →
oxffff © (2007-11-19 14:05) [51]
> Anatoly Podgoretsky © (19.11.07 13:34) [50]
Да я еще на одни такие грабли наткнулся. Но уже в Delphi реализации.
Грабли следующие
Запустите следующий код
var a:TADODataSet;
b:string;
begin
inherited;
a:=TADODataSet.Create(nil);
b:=b+"select * from abc where a=:param1";
a.Parameters.ParseSQL(b,true);
showmessage(b);
и посмотрите чему равно b
← →
Anatoly Podgoretsky © (2007-11-19 14:09) [52]> oxffff (19.11.2007 14:05:51) [51]
Зачем в угадайку играть?
Но меня здесь смучает b+, зачем?
← →
oxffff © (2007-11-19 14:13) [53]
> Anatoly Podgoretsky © (19.11.07 14:09) [52]
> > oxffff (19.11.2007 14:05:51) [51]
>
> Зачем в угадайку играть?
> Но меня здесь смучает b+, зачем?
А затем чтобы счетчик был не FFFFFFFF.
← →
oxffff © (2007-11-19 14:16) [54]b:="select * from abc where a=:param1";
a.Parameters.ParseSQL(b,true);
showmessage(b);
на экране select * from abc where a=:param1
А если
b:=b+"select * from abc where a=:param1";
a.Parameters.ParseSQL(b,true);
showmessage(b);
на экране select * from abc where a=?
← →
Сусл © (2007-11-19 14:20) [55]
> [49] Anatoly Podgoretsky © (19.11.07 13:30)
>
> WHERE DT=:DT
> при любых DT как минимум компилирование будет только один
> раз, но также сработает и статистика, в результате если
> 19 числа запрос выполнялся за 30 секунд, то 20 возможно
> уже за 10 секунд.
ты эта, невнимательно мой пост прочел.
← →
Anatoly Podgoretsky © (2007-11-19 14:23) [56]Что то с оптимизацией и со ссылками в строках. Второй вариант работает не правильно. Что именно не пойму, но это последствие b+ и то что функция ParseSQLиспользуется как процедура.
Во втором варианте есть побочное использование b, результат почему то помещенно в нее.
Сейчас проверю на своем компиляторе.
← →
Anatoly Podgoretsky © (2007-11-19 14:25) [57]
> ты эта, невнимательно мой пост прочел.
Разве нет, если не понял, то доведи свою мысль. Мой ответ касается MS SQL и как подготавливаются запросы, если в запросе будет изменен хотя бы один символ, то он будет перекомпилирован, со статистикой 0 и неизвестным планом.
← →
oxffff © (2007-11-19 14:26) [58]
> Anatoly Podgoretsky © (19.11.07 14:23) [56]
А вы посмотрите реализацию ParseSQL.
И все станет ясно.
Я на эти грабли 2 часа убил.
← →
sniknik © (2007-11-19 14:27) [59]> А если
а если сделать правильно?
...
b:= a.Parameters.ParseSQL(b,true);
...
(параметр b, не var чтобы расчитывать на возврат)
← →
oxffff © (2007-11-19 14:30) [60]
> sniknik © (19.11.07 14:27) [59]
Вы что-то не поняли.
b:=b+"select * from abc where a=:param1";
a.Parameters.ParseSQL(b,true);
showmessage(b);
на экране будет select * from abc where a=?
А не "select * from abc where a=:param1
← →
Anatoly Podgoretsky © (2007-11-19 14:33) [61]Проверил.
В Д7 ошибка есть, и не зависит присваивается ли результат функции переменной.
В Д10 ошибка устранена.
← →
Anatoly Podgoretsky © (2007-11-19 14:35) [62]
> sniknik © (19.11.07 14:27) [59]
Строки это очень хитрая вещь, могут быть любые сюрпризы, тем более когда в таком странном виде.
← →
oxffff © (2007-11-19 14:37) [63]
> Anatoly Podgoretsky © (19.11.07 14:33) [61]
Во во, И я о том же. Сидел и думал почему, когда я делаю так
Dataset.ParamCheck:=false;
Dataset.CommandText:=Dataset.Parameters.ParseSQL(SQL,true);
Dataset.Parameters.ParseSQL(SQL,true);
showmessage(Dataset.Parameters.ParseSQL(SQL,true)) дает 0. :)
Пришлось поправить на
Dataset.ParamCheck:=false;
Dataset.CommandText:=Dataset.Parameters.ParseSQL(DupeString(SQL,1),true);
Dataset.Parameters.ParseSQL(SQL,true);
← →
oxffff © (2007-11-19 14:38) [64]
> showmessage(Dataset.Parameters.ParseSQL(SQL,true)) дает
> 0. :)
showmessage(inttostr(Dataset.Parameters.count));
← →
oxffff © (2007-11-19 14:42) [65]
> sniknik © (19.11.07 14:27) [59]
> > А если
> а если сделать правильно?
> ...
> b:= a.Parameters.ParseSQL(b,true);
> ...
> (параметр b, не var чтобы расчитывать на возврат)
Запустите
a:=TADODataSet.Create(nil);
a.Connection:=ADOConnection;
b:=b+"select * from abc where a=:param1";
c:=a.Parameters.ParseSQL(b,true);
if pointer(b)=pointer(c) then showmessage("Idential Ref");
← →
sniknik © (2007-11-19 14:58) [66]> Запустите
я понял что ты хочеш сказать с первого раза...
но учитывая
Anatoly Podgoretsky © (19.11.07 14:35) [62]
> Строки это очень хитрая вещь
+ отсутствие var для параметра, + что строка это всетаки указатель и работа в процедуре идет с ней по адресу (value:= PChar(...)) + непонятное(бессмысленное) компилятору действие
=
> а если сделать правильно?
и получать выражение (если оно нужно) оттуда где оно гарантируется.
← →
oxffff © (2007-11-19 15:12) [67]
> sniknik © (19.11.07 14:58) [66]
Строки не хитрее нас с вами.
Что значит гарантируется?
Если передается параметр по значению.
То его значение не должно меняться.
Это правило.
>и получать выражение (если оно нужно) оттуда где оно гарантируется.
мне нужен результат и неизмененоое значение входного параметра.
А то что эта функция производят прямое взаимодействие со строкой и нарушает семантику типа. То это БАГ.
← →
Anatoly Podgoretsky © (2007-11-19 15:26) [68]> oxffff (19.11.2007 15:12:07) [67]
Это баг, но привел к нему ты, кострукцией B := B + Text
Баг устранен в следующей версии Дельфи.
← →
oxffff © (2007-11-19 15:34) [69]
> Anatoly Podgoretsky © (19.11.07 15:26) [68]
Что значит я привел?
То есть вы хотите сказать, что это нормально?
А правильно вас понял?
← →
Сусл © (2007-11-19 15:34) [70]
> [57] Anatoly Podgoretsky © (19.11.07 14:25)
>
> > ты эта, невнимательно мой пост прочел.
>
> Разве нет, если не понял, то доведи свою мысль. Мой ответ
> касается MS SQL и как подготавливаются запросы, если в запросе
> будет изменен хотя бы один символ, то он будет перекомпилирован,
> со статистикой 0 и неизвестным планом.
запрос все равно в большинстве случаев выливается в вызов sp_executesql
так тебе никто не мешает самому пользоваться ентой штукой.
вот о чем речь.
← →
oxffff © (2007-11-19 15:36) [71]
> Это баг, но привел к нему ты, кострукцией B := B + Text
Да какая конструкция. Эта конструкция нужна для того, чтобы выявить бажную ситуацию. И сделано для того, чтобы строка была в куче, а сегменте данных. Я же вам написал
oxffff © (19.11.07 14:13) [53]
oxffff © (19.11.07 14:30) [60]
← →
oxffff © (2007-11-19 15:39) [72]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) [73]> oxffff (19.11.2007 15:34:09) [69]
Нет, я так не говорил, это не нормально, как ошибка, так и код.
Твое объяснение насчет ссылок меня не убедило.
← →
Anatoly Podgoretsky © (2007-11-19 15:40) [74]> oxffff (19.11.2007 15:36:11) [71]
Я возможно не понимаю истинной цели данной операции.
← →
Anatoly Podgoretsky © (2007-11-19 15:43) [75]> Сусл (19.11.2007 15:34:10) [70]
Можно много чего, но я предпочту стандартный механизм. Но если ты обеспечишь изменение запроса, что бы получилось where a=? и сумеешь передать параметры, тогда да, но тогда это ничем не будет отличаться от стандартного пути + некоторый геморой.
А как выполняются запросы в MS SQL неплохо описано в BOL, я попытался рассказать на рабоче-крестьянском. Ведь если я даже и стремлюсь переубедить тебя, то не очень настойчиво.
← →
oxffff © (2007-11-19 16:09) [76]
> 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
← →
oxffff © (2007-11-19 16:11) [77]
> oxffff © (19.11.07 16:09) [76]
А далее идет прямое обращение со строкой приводя ее к pchar, тем самым нарушая семантику типа.
Отсюда грабли.
Теперь понятно??
← →
Anatoly Podgoretsky © (2007-11-19 16:15) [78]> oxffff (19.11.2007 16:09:16) [76]
Это то понятно, а вот цель нет.
← →
sniknik © (2007-11-19 16:21) [79]> Теперь понятно??
а вот теперь мне не понятно, получается ты специально "сбил настройки", в полном уме и трезвой памяти, а после удивляешься "ой, а тут получается разный результат", получая этот результат оттуда откуда не должен...
зачем?
← →
oxffff © (2007-11-19 16:30) [80]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);
не создает параметров. По скольку в строке уже их нет.
Чего не понятно то?
← →
Anatoly Podgoretsky © (2007-11-19 16:34) [81]> oxffff (19.11.2007 16:30:20) [80]
Непонятно зачем, ты объясняешь как, а не почему (зачем).
← →
oxffff © (2007-11-19 16:36) [82]
> Anatoly Podgoretsky © (19.11.07 16:34) [81]
Что почему?
← →
Anatoly Podgoretsky © (2007-11-19 16:43) [83]> oxffff (19.11.2007 16:36:22) [82]
Ладно проехали, раз не понял.
Но вот что я наблюдаю, гляда за тобой, ты часто применяешь рискованые вещи, иногда действительно нарываешь на баг, а чаще на то, что твое представление не совпадает с представлением компилятора. Но это твое право.
← →
oxffff © (2007-11-19 16:56) [84]
> Anatoly Podgoretsky © (19.11.07 16:43) [83]
Пожалуйста тыкните меня носом в то место, где мое представление о работе компилятора не совпадает, а то знаете не хорошо так.
← →
Anatoly Podgoretsky © (2007-11-19 16:59) [85]> oxffff (19.11.2007 16:56:24) [84]
Ну не буду же я извлекать все сообщения из форумов, это мое наблюдение, ты часто жалуешься, что обнаружил баг, и потом идет разборка баг или нет. Неужели я тебя с кем то перепутал?
← →
oxffff © (2007-11-19 16:59) [86]Anatoly Podgoretsky © (19.11.07 16:43) [83]
Знаете а у меня кстати сложилось обратное впечатление,
где вы и господин sniknik © пытались убедить меня в том, что нарушение семантики типа и правил языка - это нормально.
← →
oxffff © (2007-11-19 17:03) [87]
> Anatoly Podgoretsky © (19.11.07 16:59) [85]
Во первых я не жалуюсь.
А во вторых, если я и говорю об этом. То все это были действительно баги, о которых я написал в QC.
За исключеним одного случая, где было выравнивание в стеке по границе DWORD. Но Сергей М. меня поправил. Я правда об этом не знал.
В чем и признался.
А все остальное были баги.
Так что будьте более внимательны.
← →
Anatoly Podgoretsky © (2007-11-19 17:03) [88]> oxffff (19.11.2007 16:59:26) [86]
Может и пытался, хотя обычно обхожу стороной подобные ветки. Эта просто меня заинтересовала, решил проверить на разных версиях. А применять подобное никогда не буду. Конечно грабли это бесченный опыт, но можно и без него.
А ты что решил наехать? Так зря, я как то безраличен.
← →
Сусл © (2007-11-19 17:04) [89]сергей, обсуждай это в новостных группах бета-теста, чессо слово полезней будет.
не, не то чтобы здесь люди неправильные и не понимают, просто они пользователи дельфи, а не разработчики. нарвись лучше на разработчика по дельфи в указанных новостных группах. вот там можно очень неплохо сцепица :)
вообще, совет - постарайся найти тест-кеэс без АДО, просто - ошибка компилятора. тогда тебе легко удасться сцепиться с тем же пьером ле ришем. правда, очень вероятно, что он тебе докажет - as designed :)
← →
oxffff © (2007-11-19 17:07) [90]
> Anatoly Podgoretsky © (19.11.07 17:03) [88]
У меня есть уважение к более старшим товарищам. И всегда будет оставаться. И к вам лично также.
Просто я уже стал давно замечать, что у старших товарищей звездит.
И они не всегда реально представляют ситуацию.
Но настораживает другое. Они не то, что не слышат, а не хотят слушать.
Это печально.
← →
oxffff © (2007-11-19 17:12) [91]
> Сусл © (19.11.07 17:04) [89]
Anatoly Podgoretsky уже проверил на 10 версии. Там исправили.
Я пока на работе на 7.
Но это побочный баг. А баг провайдера нужно в Microsoft. Либо более свежую версию OLEDB провайдера качнуть.
Может у меня старый.
← →
sniknik © (2007-11-19 18:04) [92]> Начнем по порядку.
> 1. Баг1 не некорректная обработка параметров провайдером.
> --> Решение
начнем. я тебе сразу сказал что решение неэффективное, нормально все делается через CreateParameter, в одну строку. сказал и решил что проблема решена...
а то что ты привел с "парсе" думал ты делаешь ради результата, распарсеной строки (потому как удивление вызывал сам факт разного результата, а не то что изменений не должно быть (необъяснено, что делается, поэтому подставлен ближайший смысл)), а результат ты получал через одно место где нет var... и которое если меняется то само изменение ошибочно.
так понятно?
> Они не то, что не слышат, а не хотят слушать.
в зеркало посмотри...
← →
sniknik © (2007-11-19 18:08) [93]> Либо более свежую версию OLEDB провайдера качнуть.
подсократить запрос, тоже проигнорировал... а могло бы помочь и без провайдера. (хотя обновления нужно в любом случае)
p.s. еще раз в зеркало посмотри.
← →
Anatoly Podgoretsky © (2007-11-19 18:32) [94]> Сусл (19.11.2007 17:04:29) [89]
И в Д7 as designed и в Д2006?
Поведение разное.
← →
Anatoly Podgoretsky © (2007-11-19 18:33) [95]> oxffff (19.11.2007 17:12:31) [91]
> Anatoly Podgoretsky уже проверил на 10 версии. Там исправили.
Мог бы и поверить мне, я же написал, что проверил и на 7 и на 10
← →
Anatoly Podgoretsky © (2007-11-19 18:35) [96]> sniknik (19.11.2007 18:08:33) [93]
Я проверял без установки свойств
← →
oxffff © (2007-11-19 18:42) [97]
> sniknik © (19.11.07 18:04) [92]
> начнем. я тебе сразу сказал что решение неэффективное, нормально
> все делается через CreateParameter, в одну строку. сказал
> и решил что проблема решена...
А я сказал, что не нельзя так решать.
Запросы формируются на лету.
Состав параметров в одном и том же запросе (по смыслу) может меняться.
Причем запросы (по смыслу) могут добавляться и меняться его варианты на (разновидности) на лету.
Поэтому создавать для каждого варианта - список параметров и создавать их через CreateParameter - это извините через одно место.
И предлагаете это не я, а вы.
>подсократить запрос,
Вы что царь бог, который все знает.
Если запрос большой,то это не значит что он неправильный.
Вы опять не внимательны. Посмотрите каждый подзапрос выбирает различный срез информации.
>а результат ты получал через одно место где нет var... и которое если >меняется то само изменение ошибочно.
То есть если функция принимает параметр по значению.
А ссылочная семантика string позволяет изменить строку переданное по значению, но это будет нарушение семантики типа.
То есть вы в очередной раз хотите сказать что нарушение семантики типа - это не баг. И почему то приписываете бажную реализацию мне, а не библиотеки в Delphi.
См. function ParseSQL(SQL: String; DoCreate: Boolean): String;
И если я вынужден так делать по причине того, что провайдер не обрабатывает параметры запроса.
У меня складывается впечатление, что либо вы не внимательно читали тему, либо не понимаете сути разговора.
← →
oxffff © (2007-11-19 18:46) [98]
> Anatoly Podgoretsky © (19.11.07 18:33) [95]
Так я вам и поверил же.
Сам еще не проверил.
Однако придется остановиться на 7.
На работе все на 7 пишут.
C уважением Антонов Сергей. :)
← →
Anatoly Podgoretsky © (2007-11-19 19:07) [99]> oxffff (19.11.2007 18:46:38) [98]
Я могу еще кое что добавить, это ошибки Борланда при работе с параметрами, особенно WideString, они наблюдаются начиная с версии 5 и в 7 они еще не устранены, только 10 более менее удовлетворяет.
Ошибки дурные и неисправимые. Они связаны например с внутренним зеркальным объявлением и они не лечатся даже исправлением генофонда, попытки компилировать ни к чему не приводят, ни ошибок нет, но и dcu file нет, похоже это из-за интерфейсов или черт его знает из-за чего.
Из-за этих очень обидных ошибок и необходимости работать с Юникод мне пришлось перейти на 10.
Поэтому советую и вам серьезно задуматься над этим шагом.
У меня переход был бесболезненый, ни единого изменения, просто перекомпиляция проекта, но это возможно из-за того, что не использую посторонних компонент, только TNT
← →
oxffff © (2007-11-19 19:21) [100]
> Anatoly Podgoretsky © (19.11.07 19:07) [99]
Да я бы с радостью. Но завязаны на компонентах под 7.
Что касаемо реализации ParseSQL на 10. Они поменяли на widestring.
А в реализации семантики addref присутствует создание дублеката с помощью SysAllocStringLen.
← →
Anatoly Podgoretsky © (2007-11-19 19:35) [101]> oxffff (19.11.2007 19:21:40) [100]
Мне было проще, но и очень большая нужда в Юникод, попутно они там устранили ошибку и с автоинкриментрыми полями и кое что с целыми, но мне интересно как они вообще могли допустить такие простые, детские ошибки.
← →
oxffff © (2007-11-19 19:47) [102]
> Anatoly Podgoretsky © (19.11.07 19:35) [101]
я надеюсь невнимательность. :)
← →
Anatoly Podgoretsky © (2007-11-19 19:56) [103]> oxffff (19.11.2007 19:47:42) [102]
Ох если бы, по моему не понимание технологии и пофигизм.
← →
sniknik © (2007-11-19 21:10) [104]> А я сказал, что не нельзя так решать.
а я тебе не верю...
> Запросы формируются на лету.
> Состав параметров в одном и том же запросе (по смыслу) может меняться.
но они же есть! и через "парсе", ты их тоже создаешь, а после через parambyname (или по индексу) присваиваешь значение, и это не мешает "динамичности", не будет и "мой" метод мешать. он только упрощает, вместо 3 действий будет одно. (для 1 параметра, для 2х вместо 4-х 2-ва и т.д.)
> и создавать их через CreateParameter - это извините через одно место.
ну... это смотря у кого где руки.
> И предлагаете это не я, а вы.
ага. я всегда стараюсь все упростить. и всем предлагаю. но не хотят.
> Вы что царь бог, который все знает.
с вами станешь... хотя я всегда отвечаю на восклицание типа "какой ты умный" - "я нормальный это ты идиот/ка" (даже поссорился с девушкой один раз...)
> Если запрос большой,то это не значит что он неправильный.
если запрос большой, значит он большой (я не говорил неправильный), и если его можно написать проще значить нужно написать проще. а заодно может и парсер в его дебрях путаться перестанет. (не факт но...)
> Вы опять не внимательны. Посмотрите каждый подзапрос выбирает различный срез информации.
в зеркало похоже не смотрел...
я то как раз внимательный, и вижу возможность (если конечно в "волшебных пузырьках" - "..." таже прогрессия что задана в первых двух вариантах подзапросов)
например возможность раз
записать
from (select convert(char(10),Traindate,2) as value
from SourceTrains group by convert(char(10),Traindate,2)
) A
в виде
from (select distinct convert(char(10),Traindate,2) as value from SourceTrains) A
сеть одна, но убирается 1 функция работы со строкой
либо вообще
from (select distinct DateAdd(d, 0, DateDiff(d, "", Traindate)) as value from SourceTrains) A
тогда и значение (value) будет нормальной датой, а не строкой (формат локальный сработает...).
возможность номер 2
вся эта байда вообще не нужна, если ВЫ посмотрите внимательнее на СВОЙ запрос, то заметите что объединения делаются по одним и тем же таблицам, и одним и тем же связующим полям... а результат всего лиш подсчет количества...
т.е. это все можно свести к единственному запросу с группировкой по дню, а результаты полей считать условиях (CASE), т.е. все (либо хотябы часть) запросы с одинаковыми алиасами, и кучей джойнов, в которых парсер наверняка и путается, сведутся к одному запросу с одним объединением... парсер будет "счастлив".
> И почему то приписываете бажную реализацию мне, а не библиотеки в Delphi.
не реализацию, читай тщательнее, а получение значения из неправильного места. котороя я думал ты получаешь (см. обьяснения в прошлом топике. и обьяснения почему я так думал. заблуждение ввиду отсутствия информации на тот момент, о том что делалось.)
p.p.s. а вообще нафиг. писать без надежды на понимание (притом еще и меня обвиняют, вместо того чтобы в зеркало посмотреть), смысла наверное нет. пока.
← →
sniknik © (2007-11-19 21:16) [105]а да. чуть не забыл, могу выложить свою программку (на "своих" принципах ;о)), в которой можно проверить запрос, с динамическим(! о как ;), и мне не мешает) созданием запросов, и параметров (до 10-и, ограничение искусственное. просто так сделал)
практически уверен (процентов 90 даю), что в нем ваш запрос сработает.
(это чтобы не быть голословным)
← →
oxffff © (2007-11-19 21:51) [106]
> sniknik © (19.11.07 21:10) [104]
Может хватит уже фантизировать.
>но они же есть! и через "парсе", ты их тоже создаешь, а после через >parambyname (или по индексу) присваиваешь значение, и это не >мешает "динамичности", не будет и "мой" метод мешать. он только >упрощает, вместо 3 действий будет одно. (для 1 параметра, для 2х вместо >4-х 2-ва и т.д.)
Где вы увидили, что я явно параметры присваиваю.
Т.е. насколько я понял вы утверждаете, что я делаю так в коде AdoDataSet.parameters.parambyname("").value:=some value.
Знайте, что я не делаю так.
За меня это делает генератор динамически.
см.
oxffff © (19.11.07 12:40) [45]
А именно генератор смотрит параметры запроса, распарсенные parseSQL.
И обращается к поставщику параметров через интерфейс, в простом случае, это форма с компонентами, которая возвращает значения параметра по требованию.
Что и теперь будете на своем стоять?
>> И предлагаете это не я, а вы.
>ага. я всегда стараюсь все упростить. и всем предлагаю. но не хотят.
Способ, который вы предлагаете статичен и жестко зашит в код.
В моем случае мы не проводим связь между набором параметров и запросом. А делаем это по требованию. Так что, то что вы предлагаете - это реализация со статической привязкой параметров (на этапе компиляции вы делаете эту привязку в коде или XML файле).
В моей реализации делать это не надо.
Так что перед тем как предложить посмотрите в зеркало. :)
К сожалению вы здесь усложняете. См. выше.
Ну вы и фантазер.
select value,
-> всего за день 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",
-> всего за value день с 0 часов до 6 часов
(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",
... Далее идут
-> всего за value день с 0 часов до 6 часов со статусом 0
-> всего за value день с 0 часов до 6 часов со статусом 12
-> всего за value день с 0 часов до 6 часов со статусом 14
-> всего за value день с 0 часов до 6 часов со статусом 30
Далее
... с 6 до 14 часов, и со статусами и т.д.
.........
← →
oxffff © (2007-11-19 22:01) [107]
> либо вообще
> from (select distinct DateAdd(d, 0, DateDiff(d, "", Traindate))
> as value from SourceTrains) A
> тогда и значение (value) будет нормальной датой, а не строкой
> (формат локальный сработает...).
Я же говорю, вы не зная запроса предлагаете свой вариант.
А вы разве не в курсе, что здесь в вашем запросе я получу тип datetime?
А мне нужно получить просто дату, без времени.
← →
oxffff © (2007-11-19 22:04) [108]
> oxffff © (19.11.07 22:01) [107]
А далее на конкретную дату получать, Общее число,
число за интервал часов дня, число за этот интервал часов дня с различными статусами.
← →
oxffff © (2007-11-19 22:15) [109]
> не реализацию, читай тщательнее, а получение значения из
> неправильного места. котороя я думал ты получаешь (см. обьяснения
> в прошлом топике. и обьяснения почему я так думал. заблуждение
> ввиду отсутствия информации на тот момент, о том что делалось.
> )
Я не могу понять смысл вашей фразы. Кто думал? Что думал?
И что это за неправильное место такое? И кто дал ему характеристику?
Что за прошлый топик?
← →
oxffff © (2007-11-19 22:32) [110]
> т.е. это все можно свести к единственному запросу с группировкой
> по дню, а результаты полей считать условиях (CASE), т.е.
> все (либо хотябы часть) запросы с одинаковыми алиасами,
> и кучей джойнов, в которых парсер наверняка и путается,
> сведутся к одному запросу с одним объединением... парсер
> будет "счастлив".
Ну и далее то как, как вы будете выделять с помощью CASE.
количество в интервале(в часах) дня.
Пример не приведете случаем.
← →
sniknik © (2007-11-19 22:54) [111]> Может хватит уже фантизировать.
> Где вы увидили, что я явно параметры присваиваю.
смотрим в [0]
...
where trainId=:param1
...
оба на, параметр, а как же к нему идет обращение? присваивается значение? наверное путем фантазирования.
> Т.е. насколько я понял вы утверждаете, что я делаю так в коде AdoDataSet.parameters.parambyname("").value:=some value.
> Знайте, что я не делаю так.
есть собственный Хоттабыч? иначе только он может (по индексу считай это вариация того же).
> Способ, который вы предлагаете статичен и жестко зашит в код.
вот тут вы глубоко, прямотаки "не подецки" заблуждаетесь. (ложить программку? скомпиленную... ничего в нее не предзашито, какой запрос сами наберете (читайте сгенерируете, для программы это тоже самое), то и будет)
а вообще, есть одно правило в программировании - "как напишешь так и будет".
и похоже те средства которые для меня свободны для использования где угодно у тебя жестко зашиты в код.... выкини этот код. нехорошо это.
> Я же говорю, вы не зная запроса предлагаете свой вариант.
не предлагаю (еще чего не хватало), я говорю, что имеющееся (показанное) можно упростить. сильно упростить. также можно и остальное если оно "построено" аналогично.
> ... Далее идут
> ...
ну, вот именно это я и имею ввиду. аналогично. практически полный аналог.
> А мне нужно получить просто дату, без времени.
т.е. работать с датами ты тоже не умеешь... тяжело тебе. (ты ее как предложено как раз и получишь, дату без времени.)
> Я не могу понять смысл вашей фразы.
не сомневался.
> Что за прошлый топик?
ну, не так много я сюда и постил, чтоб потеряться. прошлый это значит тот что был до этого.
← →
sniknik © (2007-11-19 22:59) [112]> Пример не приведете случаем.
мог бы. но ты опоздал с этим вопросом, постов на 60...
← →
sniknik © (2007-11-19 23:06) [113]и это. не думай что я обиделся, личная неприязнь, или чего еще там... нет, мне все одно как развлекаться, просто я четко делю ветки на "деловые" и "потрепаться"... догадываешься в какую категорию попадает твоя? и почему? (подсказка - вовсе не по тому что создана в "потрепаться")
и вот теперь когда мы мило треплемся, вопрос о "доказательстве кодом" у меня уже ассоциируется с "сделай на слабо", а "на слабо" я ничего не делаю. из принципа.
← →
oxffff © (2007-11-19 23:18) [114]
> sniknik © (19.11.07 22:59) [112]
> > Пример не приведете случаем.
> мог бы. но ты опоздал с этим вопросом, постов на 60...
А вот и приведите.
И покажите как вы заставите агрегатную функцию для одного среза считать количество удовлетворяющих CASE.
А именно посчитать количество с 0 до 6 часов используя CASE без внутренних подзапросов.
А то впечатление что вы только болтать и умеете.
← →
oxffff © (2007-11-19 23:24) [115]
> sniknik © (19.11.07 22:54) [111]
> > Может хватит уже фантизировать.
> > Где вы увидили, что я явно параметры присваиваю.
> смотрим в [0]
> ...
> where trainId=:param1
> ...
> оба на, параметр, а как же к нему идет обращение? присваивается
> значение? наверное путем фантазирования.
>
> > Т.е. насколько я понял вы утверждаете, что я делаю так
> в коде AdoDataSet.parameters.parambyname("").value:=some
> value.
> > Знайте, что я не делаю так.
> есть собственный Хоттабыч? иначе только он может (по индексу
> считай это вариация того же).
Да представляете есть такой старик Хоттабыч.
Называется IparameterBroker который поставляет значения парметров по запросу для генератора.
И представлете у этого интерфейса один метод, и работает.
IparameterBroker=interface
function GetParamValue(name:string):variant;
property value[name:string]:string read GetParamValue;
end;
А реализатор этого интерфейса форма, которая связывает элементы управления и параметры.
А вы все создавайте вручную параметры с помощью CreateParameter.
Так и делайте дальше.
← →
oxffff © (2007-11-19 23:26) [116]
> sniknik © (19.11.07 22:59) [112]
> > Пример не приведете случаем.
> мог бы. но ты опоздал с этим вопросом, постов на 60...
Ну сюдя по тому, что вы мне пытались доказать что нарушать семантику типа это хорошо, я ничего не потерял.
← →
oxffff © (2007-11-19 23:29) [117]
> property value[name:string]:string read GetParamValue;
> property value[name:string]:variant read GetParamValue;
← →
oxffff © (2007-11-19 23:38) [118]
> и похоже те средства которые для меня свободны для использования
> где угодно у тебя жестко зашиты в код.... выкини этот код.
> нехорошо это.
Что вы все с ног на голову переворачиваете?
О статичном коде писали как раз вы. Неоднократно утвердая, что надо делать только через createParameter и никак иначе.
Повторяю неоднократно.
Таким образом, если вы не полагаетесь на динамический разбор SQL выражения.
А полагатесь на статическое создание параметров. Значит их кто то должен детерменированно определить и не дай бог не определит тех, которые есть в SQL выражении. Вы можете предоставить это делать в run time. Суть от этого не меняется. Если вы делаете createparameter, не полагаясь на динамичский разбор, то задать этот набор нужно детерменированно.
Статическая(compile time) привязка или run time пользователем.
Повторяю именно вы говорили о createparameter
← →
oxffff © (2007-11-19 23:43) [119]
> sniknik © (19.11.07 23:06) [113]
> и вот теперь когда мы мило треплемся, вопрос о "доказательстве
> кодом" у меня уже ассоциируется с "сделай на слабо", а "на
> слабо" я ничего не делаю. из принципа.
А я вот отчетливо вижу, когда вас прижимают к стенке,
вы начинаете давать задний ход.
← →
sniknik © (2007-11-19 23:50) [120]> что надо делать только через createParameter и никак иначе.
де не "никак иначе", а в в случае ошибки, и в других случаях когда ParamCheck отключен. (тебе же помогло отключение? вначале. помню именно после этого предложил этот вариант)
> Повторяю неоднократно.
и еще раз повторюсь. createParameter форевер! :о))
а что до статичности, то функция статичной не бывает, значение, параметры в нее в дизайне, в чем вы меня "обвиняете" попросту не задашь.
-> диагноз. у вас слишком мало знаний при большом самомнении в собственной непогрешимости.
> А я вот отчетливо вижу, когда вас прижимают к стенке,
> вы начинаете давать задний ход.
мне попросту надоело. т.что действительно пока.
впрочем предложение о проверке в программе все еще в силе (хотя и проигнорировано 2 раза)
← →
oxffff © (2007-11-19 23:50) [121]
> sniknik © (19.11.07 22:54) [111]
> > Может хватит уже фантизировать.
> > Где вы увидили, что я явно параметры присваиваю.
> смотрим в [0]
> ...
> where trainId=:param1
Этот пример приведен для выявления ошибки в провайдере.
Не более того.
Это итоговый запрос и является продуктом генератора.
← →
Сусл © (2007-11-19 23:53) [122]офигеть.
если есть баг, он запостен, он открыт, то чего обсуждать.
← →
oxffff © (2007-11-19 23:57) [123]
> -> диагноз. у вас слишком мало знаний при большом самомнении
> в собственной непогрешимости.
Ого. да вы еще и диагнозы ставите.
Куда нам до вас.
А про семантику типов вам бы не мешало прочитать.
>впрочем предложение о проверке в программе все еще в силе (хотя и >проигнорировано 2 раза)
Если вы не опасаетесь о том, что я что-нибудь найду в ней и скажу, что сделали криво?
Тогда говорите где скачать.
← →
oxffff © (2007-11-20 00:01) [124]
> Сусл © (19.11.07 23:53) [122]
Доброй ночи, Дмитрий.
Баг пофиксен в 10.
А баг провайдера я уже нашел как обходить. :)
← →
sniknik © (2007-11-20 00:03) [125]> если есть баг, он запостен, он открыт, то чего обсуждать.
тут даже 2 бага было, а обсуждать есть чего, т.к. если бы делалось нормально то они бы не помешали. а вот понятия о "нормальности" у каждого свои.
комуто они очень мешают, но ничего поделать они с ними не хотят, хотят о них поговорить.
> Если вы не опасаетесь о том, что я что-нибудь найду в ней и скажу, что сделали криво?
а вот исходников я вам не обещал. :), потому и спрашивал... вдруг вы мне не доверяете, тогда зачем ложить?
← →
oxffff © (2007-11-20 00:05) [126]
> а вот исходников я вам не обещал. :), потому и спрашивал.
> .. вдруг вы мне не доверяете, тогда зачем ложить?
Меня конечно больше интересует реализация.
Но ничего. Я все равно по внешнем данным думаю смогу сделать вывод о статичности\динамичности вашего подхода. Где взять?
← →
oxffff © (2007-11-20 00:06) [127]
> комуто они очень мешают, но ничего поделать они с ними не
> хотят, хотят о них поговорить.
Давайте обойдемся без лишнего, я все еще жду от вас реализации на CASE.
← →
sniknik © (2007-11-20 00:14) [128]> Где взять?
500мг. есть ридми, разберешься.
http://www.filefactory.com/file/a2c2f4/
> я все еще жду от вас реализации на CASE.
можеш поискать в базах... месяца не прошло предлагал решение на похожую задачу.
← →
oxffff © (2007-11-20 00:19) [129]
> можеш поискать в базах... месяца не прошло предлагал решение
> на похожую задачу.
А что написать сложно?
Как вы сделаете count в каждом поле и магическим образом заставите складывать только те значение которые удовлетворяют условию.
Причем в каждом столбце условия разные?
Что это за хитрый какой синтаксис, если он есть?
← →
oxffff © (2007-11-20 00:31) [130]
> sniknik © (20.11.07 00:14) [128]
Я честно говоря совсем не понял где у вас здесь динамическое формирование запроса.
Кроме 10 шаблонов.
CREATE TABLE [Table] (Field Type)
Куда нажать?
Чтобы сформировать where с AND или OR, NOT? Это возможно?
← →
oxffff © (2007-11-20 00:35) [131]
> sniknik © (20.11.07 00:14) [128]
Если, это все что она может, только 10 шаблонных запросов, то я бы вам даже двойку не поставил. Это детская поделка 2 курса. Не более.
А вы мне тут о параметрах. Учите мат часть. И help заодно.
Да и case не забудьте.
← →
sniknik © (2007-11-20 00:36) [132]> А что написать сложно?
принципы дело серьезное...
> Как вы сделаете count
count не единственная агрегирующая функция,
> в каждом поле и магическим образом заставите складывать только те значение которые удовлетворяют условию.
легко! причем необязательно заставлять складывать "только те" (хотя и это можно), можно "не тем" например давать значение 0, а складывать все подряд.
> Причем в каждом столбце условия разные?
в каждом столбце естественно будут свои условия.
> Куда нажать?
> Чтобы сформировать where с AND или OR, NOT? Это возможно?
ручками, ручками все что угодно (считай что ТЫ генератор запроса), по синтаксису того провайдера что выбран, либо задай предопределение с "AND или OR, NOT", параметры по правой кнопке мыши, а вообще читай ридми.
← →
sniknik © (2007-11-20 00:39) [133]> Это детская поделка 2 курса. Не более.
это писалось в 2000м году (правда еще пару тройку раз добавлялось кое чего по надобности), для изучения ADO. не менее.
← →
oxffff © (2007-11-20 00:41) [134]
> sniknik © (20.11.07 00:39) [133]
Собственно у меня другая задача. Я думаю спор из-за непонимания
← →
oxffff © (2007-11-20 00:43) [135]
> sniknik © (20.11.07 00:39) [133]
Сейчас я попытаюсь объяснить задачу.
← →
sniknik © (2007-11-20 00:46) [136]> Сейчас я попытаюсь объяснить задачу.
а... ну я так понимаю запрос тот сработал? :)))
← →
oxffff © (2007-11-20 00:52) [137]Часто приходиться писать интерфейсы для которых приходиться делать различные фильтры. Но поскольку часть фильтров может отключаться включаться, то часть приходиться писать код который собирает where выражение. А фильтры могут состоять из вариантов.
Я смотрю и думаю, а зачем если я могу формировать это предложение динамически.
Таким образом моя задача написать генератор и правила к нему, чтобы облегчить оную задачу.
И получается следующее.
TQueryGenerator.create("base sql выражение",
[
TAloneFilter.create("AND","фильтр выражение"),
TMultiFilter.create("OR",["фильтр выражение1","фильтр выражение2"])
]
TQueryGenerator.Reopen([0,0],ParamerBroker);
← →
oxffff © (2007-11-20 00:53) [138]
> а... ну я так понимаю запрос тот сработал? :)))
У меня не стоит дома SQL сервер.
← →
oxffff © (2007-11-20 00:58) [139]
> sniknik © (20.11.07 00:46) [136]
> > Сейчас я попытаюсь объяснить задачу.
> а... ну я так понимаю запрос тот сработал? :)))
Только, чтобы он сработал. Вам нужно щелкнуть правой кнопой и добавить параметр вручную. Вот тут и есть статика.
А как же насчет CASE?
← →
oxffff © (2007-11-20 01:07) [140]
> sniknik © (20.11.07 00:36) [132]
> > А что написать сложно?
> принципы дело серьезное...
>
> > Как вы сделаете count
> count не единственная агрегирующая функция,
>
> > в каждом поле и магическим образом заставите складывать
> только те значение которые удовлетворяют условию.
> легко! причем необязательно заставлять складывать "только
> те" (хотя и это можно), можно "не тем" например давать значение
> 0, а складывать все подряд.
А если вы выкрутитесь на sum то 0, то 1, но тогда большая часть у вас будет холостой ход, поскольку большая часть не будет попадать в заданный диапазон.
← →
ЮЮ © (2007-11-20 03:42) [141]> А если вы выкрутитесь на sum то 0, то 1, но тогда большая
> часть у вас будет холостой ход, поскольку большая часть
> не будет попадать в заданный диапазон.
из SourceTrains и SourceVagons ОДИН РАЗ получаем выборку вида
TrainDayOnly, Total, Total06, Total0612, ..., содержащую только 0 и 1( благодаря case). Причем хотя бы в одном столбце будет 1, т.к. WHERE часть никто не отменял и мы анализирируем лишь те строки, которые войдут в нужную статистику.
А теперь по этой выборке делаем суммирование.
И где здесь холостой ход? А вот многократный full scan в каждом твоем "подзапросе" просто гарантирован.
← →
oxffff © (2007-11-20 08:50) [142]
> ЮЮ © (20.11.07 03:42) [141]
Беседа зашла далеко от темы. Ну хорошо.
Вы будете группировать по дню. Воответственно в группу попадут все записи за день. А case будет делать нужный срез в группе.
Причем будет пробегать по всей группе
(обрабатывая и те, которые не войдут в срез.
Все что не попадает будет заменяться на 0, на все что попадает на 1.
И делать это надо для каждого среза.
А sum обрабатывает все записи в группе.
Я сейчас не готов дать оценку производительности.
Да и не ставил я перед собой такую задачу по оптимизации.
Однако я соглашусь c sniknik и с вами, что есть резерв для оптимизации этого запроса, в том числе и case+sum.
Поскольку вопрос не затрагивал оптимизацию запроса,
а имеел отношение непосредственно в багу провайдера.
и в результате мною был найден еще один баг.
считаю вопросы касающиеся вида и формы запроса, не имееющим отношения в предмету вопроса.
Нельзя оправдывать баги видом и сложностью запроса.
← →
sniknik © (2007-11-20 09:14) [143]> Вам нужно щелкнуть правой кнопой и добавить параметр вручную.
там все вручную, я не пытаюсь автоматизировать собственную умственную деятельность по составлению запросов как в [137] (блин, раньше не мог сказать какими глупостями занимаешься? тут я тебе не помошник)
но отговаривать не буду, догадываюсь о реакции.
> Вот тут и есть статика.
и где же тут она? ты задаешь маски (не в dataset статически ка ты видать думаешь вносишь), далее вводишь (генерируешь) запрос с любыми параметрами из возможных масок, они динамически поставляются, если нужны, будь их там 1 или 10 неважно. это именно динамика, если ты статически их занесешь в dataset а в запросе их не будет, будет ошибка (вроде бы... не делал так, как ты говоришь я делаю).
> А если вы выкрутитесь на sum то 0, то 1,
просто да? а догадаться не смог.
> но тогда большая часть у вас будет холостой ход, поскольку большая часть не будет попадать в заданный диапазон.
??? и все одно полная уверенность в своей непогрешимости.
ЮЮ © (20.11.07 03:42) [141]
> А вот многократный full scan в каждом твоем "подзапросе" просто гарантирован.
ага, гарантия на фул скан 100%, и статистика работать не будет, условия по расчетным данным. и памяти на 10? 20? в общем на n произведений таблиц в объединениях немало уйдет.
1 запрос с "холостыми ходами" по сумме на 1 число, это будет на n раз (ровно на количество запросов объединений) выгоднее чем оно счас есть (временем на работу с числом можно пренебречь т.к. оно будет очень мало в сравнении с построением объединения).
← →
sniknik © (2007-11-20 09:17) [144]> Нельзя оправдывать баги видом и сложностью запроса.
а кто их оправдывает?
тебе лиш сказали, что "делал бы нормально, и даже бы их не заметил"...
но ты предпочитаешь в них "упереться" и "обсасывать" до последнего.
← →
oxffff © (2007-11-20 09:42) [145]
> но отговаривать не буду, догадываюсь о реакции.
Да почему же, я всегда открыт к обсуждению.
> > Вот тут и есть статика.
> и где же тут она? ты задаешь маски (не в dataset статически
> ка ты видать думаешь вносишь), далее вводишь (генерируешь)
> запрос с любыми параметрами из возможных масок, они динамически
> поставляются, если нужны, будь их там 1 или 10 неважно.
> это именно динамика, если ты статически их занесешь в dataset
> а в запросе их не будет, будет ошибка (вроде бы... не делал
> так, как ты говоришь я делаю).
Генератору указываются какие фильтры использовать. И предоставляется поставщик параметров. Это динамика.
Однако сформировать фильтры придется статично.
Это касается сложных фильтров. И здесь ваш инструмент оказал бы содействие.
Однако есть возможность часть фильтров формировать в динамике.
Для этого производить анализ схемы БД.
Например срез по внешнему ключ, умножение и т.п.
Конечно эти правила будут задаваться в статике (compile time) + run time by user. Но формирование фильтра, интерфейса, разбор параметров будет в динамике.
> > А если вы выкрутитесь на sum то 0, то 1,
> просто да? а догадаться не смог.
> > но тогда большая часть у вас будет холостой ход, поскольку
> большая часть не будет попадать в заданный диапазон.
> ??? и все одно полная уверенность в своей непогрешимости.
>
Да нет же. Я данном случае вы правы, запрос можно оптимизировать.
И данном случае умножение множества будет производиться дольше чем
число-дробилка с sum+case.
Однако я не ставил перед собой этой цели, поскольку голова погружена только в этот небольшой Framework.
> > Нельзя оправдывать баги видом и сложностью запроса.
> а кто их оправдывает?
> тебе лиш сказали, что "делал бы нормально, и даже бы их
> не заметил"...
> но ты предпочитаешь в них "упереться" и "обсасывать" до
> последнего.
Гарантии, того что он не свалиться на case нет.
← →
sniknik © (2007-11-20 11:01) [146]> Да почему же, я всегда открыт к обсуждению.
оно и видно, ни на одно предложение нет "конструктива" типа "не понимаю зачем но возможно это чтото даст. обьясните", только "я вам сказал что так делать нельзя и я сделал единственно правильным способом".
если кто решит перечитать ветку, тот думаю со мной согласится, подтекст всего именно такой. (с примесью "я вот делаю правильно, а оно еще и не работает. а вы еще и говорите что ошибка эта правильная", хотя так никто говорит, говорят лиш что делаешь неправильно)
> Генератору указываются какие фильтры использовать. И предоставляется поставщик параметров. Это динамика.
программе указывается какие параметры использовать. и предоставляется список их значений. это динамика.
несогласен? я ведь не перекомпилю программу на каждый твой внесенный запрос/смененного провайдера...
> Однако сформировать фильтры придется статично.
с чего это бы "придется"?
> Однако есть возможность часть фильтров формировать в динамике.
она и есть.
нажми Ctl+F в гриде. поиск сделан на фильтрах. и опять таки никаких перекомпиляций на неизвестный мне еще запрос...
> поскольку голова погружена только в этот небольшой Framework.
глупости этот твой Framework. (по описанию в [137])
устрой голосование.
мой голос за это, +1.
а объяснению не подлежит, я и более простые(/грубые такие что просто в хелпе можно посмотреть, про createparameter например) вещи зарекся тебе объяснять. а тут все на "тонких" материях...
> Гарантии, того что он не свалиться на case нет.
а я и не давал гарантий, я говорил что парсер будет "счастлив" видеть вместо монстра с кучей подзапросов (вложенность то и связи ему обрабатывать), удобочитаемый и однопроходной запрос... и возможно (!!! только возможно, хотя и с высокой долей вероятности. а возможно и там написать монстра), он не впадет в рекурсию, не израсходует все ресурсы, не выйдет за пределы какихто ограничений, не сделает в общем того что у него счас не обрабатывается и нам он "сваливается".
если перечитаешь, кстати я и ошибку то вижу не в том в чем ты... для меня ошибка это то, что она не конкретизированна, т.е. не обработана. была бы не просто AV а чтото вроде "выход за пределы ограничений на количество вложенных запросов > 10"(например), я бы тогда сразу сказал "парень ты не прав, это твой глюк а не их"... а так я этого не говорил.
p.p.p.s все, действительно хватит, работать надо.
← →
sniknik © (2007-11-20 11:09) [147]> ... не обрабатывается и нам он "сваливается".
... не обрабатывается и на чем он "сваливается".
← →
oxffff © (2007-11-20 13:23) [148]
> sniknik © (20.11.07 11:01) [146]
> > Да почему же, я всегда открыт к обсуждению.
> оно и видно, ни на одно предложение нет "конструктива" типа
> "не понимаю зачем но возможно это чтото даст. обьясните",
> только "я вам сказал что так делать нельзя и я сделал единственно
> правильным способом".
> если кто решит перечитать ветку, тот думаю со мной согласится,
> подтекст всего именно такой. (с примесью "я вот делаю правильно,
> а оно еще и не работает. а вы еще и говорите что ошибка
> эта правильная", хотя так никто говорит, говорят лиш что
> делаешь неправильно)
То есть вы в очередной раз утверждаете, что мой запрос является причиной бага.
И что запросы нужно обязательно писать в строго определенной форме, чтобы не вызывать баги
Слышай от вас это более чем странно.
Запрос не является причиной бага. Причиной бага является ошибка.
Если вы забыли, то я сам и нашел способ обхода бага, без именения конструкции.
А вы же на протяжение всей ветки доказываете, что мой запрос является причиной бага.
Но я вам в очередной раз повторяю, что я не пытался изменить запрос (и даже не рассматривал это)
и не обращал внимания на ваши выпады в сторону изменения запроса, поскольку к делу отношения не имеют.
Далее вы пытались обвинить меня в другом мною найденном баге, но уже в Delphi.
И пытались доказать что этот баг, это не баг вовсе. Что так и должно быть
Это уже еще более чем странно.
>
> > Генератору указываются какие фильтры использовать. И предоставляется
> поставщик параметров. Это динамика.
> программе указывается какие параметры использовать. и предоставляется
> список их значений. это динамика.
> несогласен? я ведь не перекомпилю программу на каждый твой
> внесенный запрос/смененного провайдера...
Ваша программа это просто обыкновенный текстовый редактор, не более того.
А вся функциональность сводится к набору текста.
Т.е. формирование всей логики запроса статично прописано пользователем и не может измениться.
Более того параметры вообще приделаны где-то сбоку.
Где сопоставление реально используемых параметров и заданных?
Синтаксис проверяется на этапе выполнения SQL выражения.
ТО есть ваша программа оперирует с понятием текст, а не запрос
Нужно OR, AND, NOT, EXISTS, iN, соединение и т.п. Надо? Пиши текст?
>
> > Однако сформировать фильтры придется статично.
> с чего это бы "придется"?
> > Однако есть возможность часть фильтров формировать в
> динамике.
> она и есть.
> нажми Ctl+F в гриде. поиск сделан на фильтрах. и опять таки
> никаких перекомпиляций на неизвестный мне еще запрос...
А почему тогда сразу не в текстовом редакторе?
Запрос формируется статично пользователем, и не может изменять свою форму без участия пользователя - т.е. нет динамичности
Во это меня вообще удивило.
SELECT * INTO [Сведения о заказах] FROM [Сведения о заказах]
А что мне здесь опять править вручную destenation?
Могу я выбрать таблицу назначения отдельно. Или опять текст
Вообщем, не позорьтесь со своей детской неподелкой.
>
> > поскольку голова погружена только в этот небольшой Framework.
>
> глупости этот твой Framework. (по описанию в [137])
Если у вас нет фантазии, какое отношение это имеет ко мне?
> а объяснению не подлежит, я и более простые(/грубые такие
> что просто в хелпе можно посмотреть, про createparameter
> например) вещи зарекся тебе объяснять. а тут все на "тонких"
> материях...
Ну в свете того, что вы мне пытались доказать, что нарушение семантики - это не баг.
А ваши параметры, которые вообще сбоку и нет их контроля.
Читать хелп явно нужно не мне, а вам и начать с самых азов.
Страницы: 1 2 3 4 вся ветка
Текущий архив: 2008.04.13;
Скачать: CL | DM;
Память: 0.97 MB
Время: 0.009 c