![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
[D2010] Магия мыши в TSQLQuery + DateTimePicker [MySQL]
megavoid © (2010-12-14 20:13:00)Здравствуйте, Мастера!
Столкнулся с такой проблемой:
Есть форма, на ней stringgrid, sqlquery, datetimepicker. Юзеры выбирают дату в datetimepicker, в onChange конструируется select с нужной датой, выполняется через query, в цикле (query.next) читаю ответ от query и заполняю stringgrid нужными значениями. Всё вроде бы шоколадно, но есть одно но - если выбирать значение в picker'e мышью (sic!), то query при попытке интерпретировать ответ (.asString, .asInteger) выдаёт ошибку: Query: Field 'N1' not found. Не всегда выдаёт, произвольно, один раз из десяти-пятнадцати. Если же выбирать дату в пикере стрелочками, всё прекрасно, никакой ошибки. Более того, по событию FormCreate отрабатывает datetimepickerchange(self), и при запуске проги в гриде тоже всё прекрасно отображено.
Усугубляет разброд в моём мозге то, что поидее сообщения вообще выдаваться не должно бы (try..except), а оно выдаётся :)
Выглядит же этот безобразный цикл примерно так:
try
Query.Open;
for j := 0 to query.RecordCount-1 do begin
// здесь идут блоки s := fieldbyname .asstring; .asinteger; итд
try
S := query.FieldByName('N1').AsString;
except
end;
// здесь мы эти s пихаем в stringgrid
Query.Next;
Application.ProcessMessages;
end;
finally
Query.Close;
end;
При возникновении этого глюка отладчик вылетает в окно CPU, а не на строку между try..except. Стэк вызовов процедур получается такой:
KERNELBASE.RaiseException
DatabaseError
DatabaseErrorFmt
Dataset.FieldByName
стоп указывает на инструкцию leave
перед ней call dword ptr [$7555116c] - что там у меня по этому адресу - Готт его знает, перешёл туда - там jnbe, перед ней ещё пара инструкций и нули, много-много нулей :) Увы, мой ассемблер закончился в досе на уровне mov ah, 9 int 21h, так что мне это ровным счётом ничем не помогло :)
Вопрос: что же всё-таки её вызывает, ошибку эту, если мышкой выбирать дату? Пока вопрос решён чисто по-русски, то есть юзеры (~80 человек) не выбирают мышкой, но мучит меня совесть и интерес профессиональный, что ж за фигня такая :)
Плиз хелп, всем заранее спасибо!
Anatoly Podgoretsky (2010-12-15 13:47:00) [41]> megavoid (15.12.2010 13:29:50) [50]
Ну так нету же, правильно сообщает, там вообще никаких параметров нет.
megavoid (2010-12-15 13:29:00) [42]@sniknik
там есть результат.
без(ок), с мышкой - получали мессаджбокс
Qry: Field 'dtime' not found
SELECT * FROM z WHERE ddate='2010-14-12';
[OK]
> именно так рекомендуется в любом мануале любого (пока не встречал исключений) sql сервера.
И если на следующий день заказчик захочет добавить ещё одно поле в базу, придётся ходить и везде его приписывать? В других запросах, где мне требуются только отдельные поля, я указываю их. Если нужны все - ставлю *.
Сервер MySQL гордо и одиноко стоит на core i5, 4 Гб, и по всем логам не напрягает процессор больше чем на 1% в час пик. Расширения не планируется, так что его не жалко.
> жуть. как сценарист ужастиков не пробовался? :)
Обязательно попробую после этой трёхстраничной простыни ужасов :)
> во первых параметры
ну сделаю я Qry.Params.Add(ddate=date); - это будет мне очень неудобно - sql запрос req конструируется разный, в разных местах, с разными параметрами
> во вторых for j := 0 to Qry.RecordCount-1 do ???
это да, я лох, уже догадался сам :)
> в третьих определение по имени поля внутри цикла
это из области фильмов ужасов, ага, но - работает
> в четвертых нет дизейбла контролов (датасет/стринггрид)
нет. юзеры всё равно ничего не успеют сделать, пока получаем данные
сильно подозреваю, что тоже из ужастиков
> в пятых ошибки вести в лог, и разделять в каком блоке произошли, абсолютно одинаковые не информативны.
модуль лога пишется, скоро будет
> Application.ProcessMessages;
да, не подумал. Но извне, пока работает FillGrid, никаких сообщений не придёт - всё однопоточное. Разве что может быть вариант, когда юзер нажмёт обновить, и, не дождавшись, снова нажмёт обновить - тогда в qry получится полная каша. На практике такого не случалось ни разу.
> перекладки в стринггрид
В полном соответствии с требованиями заказчика. Для справки, в этом же проекте совсем рядом есть DBGridы, прекрасно работающие - но перекладывать в стринггрид мне всё равно пришлось - вот отсюда и этот страхокод :)
> ну и в восьмых код без применения "советов", нафига он нужен? убедить нас что все правильно?
всё применял, все они в коде, всем спасибо за ответы!
Anatoly Podgoretsky (2010-12-15 13:06:00) [43]> 12 (15.12.2010 12:58:46) [46]
Загубишь ты так промышленность нашу.
Ega23 (2010-12-15 13:03:00) [44]
> Не путаю, смотри пост 28
пардон, спутал.
> Ну вот не найду никак ту тему, жалко..
> короче, ну дык и пишу же
параметры вручную прописывал, или по Paramcheck получил?
просто с ручными у меня никогда никаких проблем не было, ни под MSSQL, ни под Postgres, ни под FB.
Да, это более муторное занятие. Писанины больше. Но зато никаких проблем.
12 (2010-12-15 12:58:00) [45]
> Anatoly Podgoretsky © (15.12.10 12:34) [35]
> > но, если
> > TDateTime(Trunc( datetimepicker.date))
> Ты зачем так делаешь, вроде бы достаточно грамотный программист.
от отчаяния, когда перепробовал сначала много способов, логически более очевидных.
Ну вот не найду никак ту тему, жалко..
короче, ну дык и пишу же
case Q.Params[i].DataType of
ftDateTime: Q.Params[i].AsDateTime := P[i];
else Q.Params[i].Value := P[i];
вот все равно, просто trunc от startoftheday получался, что отличался
Anatoly Podgoretsky (2010-12-15 12:58:00) [46]> megavoid (15.12.2010 12:39:40) [40]
Я не пристаю
(с) Тайна третей планеты.
Anatoly Podgoretsky (2010-12-15 12:58:00) [47]
> Ты его, похоже, с Мегавольтом путаешь.
Не путаю, смотри пост 28
Ega23 (2010-12-15 12:49:00) [48]14 часов, 33 поста.
Может завязать отвечать на вопросы, раз ответы нафиг никому не нужны?
И конкуренции меньше на рынке будет...
megavoid (2010-12-15 12:46:00) [49]гм, признаю, я лох
стоило заменитьfor j := 0 to Qry.RecordCount-1 do begin
наwhile not Qry.Eof do begin
И всё стало прекрасно. Никакой больше ошибки.
Только по-прежнему непонятно, почему возникала - даже если предположить, что recordcount в текущий момент возвращает количество записей меньшее, чем есть на самом деле, то меньше - не больше, и тогда бы я видел данные не полностью - а они были полностью.
sniknik (2010-12-15 12:42:00) [50]> сделал сразу же, результат в [8]
там нет результата, там уверения "все правильно".
вот если бы были приведены варианты ответов, с мышкой(ошибка) и без(ок), вот тогда "результаты".
> перечислять их все через запятую?
именно так рекомендуется в любом мануале любого (пока не встречал исключений) sql сервера.
> вот тот самый метод полностью
жуть. как сценарист ужастиков не пробовался? :)
во первых параметры
во вторых for j := 0 to Qry.RecordCount-1 do ???
в третьих определение по имени поля внутри цикла
в четвертых нет дизейбла контролов (датасет/стринггрид)
в пятых ошибки вести в лог, и разделять в каком блоке произошли, абсолютно одинаковые не информативны.
в шестых Application.ProcessMessages; в цикле позволяет извне выполнить "левые" операции, например закрытие/перезапрос запроса, т.к. сам "кверик" - глобальная переменная (экономишь?), где проверка после него?
в седьмых сама "идея" перекладки в стрингрид бред.
ну и в восьмых код без применения "советов", нафига он нужен? убедить нас что все правильно?
Ega23 (2010-12-15 12:39:00) [51]
> Но как в таком случае мне отследить событие окончания приезда
> всех данных? Я положился на пример использования dbExpress,
> где так и было open - for .. recordcount - next - close
> - и всё работает.
Буратино был тупой,
Буратино был тупой,
Буратино был тупой,
Буратино был тупой,
Тупой как дрова,
Тупой как дрова,
Тупой как дрова,
Тупой как дрова
(с) Псой Короленко.
megavoid (2010-12-15 12:39:00) [52]> А зачем ты обращаешься к несуществующему параметру?
я к нему не обращаюсь. это я пробовал [21], [24]
Ega23 (2010-12-15 12:37:00) [53]
> Ты зачем так делаешь, вроде бы достаточно грамотный программист.
Ты его, похоже, с Мегавольтом путаешь.
> Добавил Qry.ParamByName('ddate').asDateTime; чтобы совсем
> уж точно. То же самое.
Всё, я так больше не могу. Это, походу, развод чей-то.
Anatoly Podgoretsky (2010-12-15 12:36:00) [54]
> не, не то же самое. Qry: Parameter 'ddate' not found - логично,
> ведь
А зачем ты обращаешься к несуществующему параметру?
megavoid (2010-12-15 12:36:00) [55]Я имею некое представление про серверный курсор. При однонаправленном датасете мы можем лишь идти курсором вперёд по набору данных, используя .Next. Да, я понимаю, что раз он работает асинхронно, то я могу начать читать записи до того, как они все приедут по сети. Но как в таком случае мне отследить событие окончания приезда всех данных? Я положился на пример использования dbExpress, где так и было open - for .. recordcount - next - close - и всё работает.
Anatoly Podgoretsky (2010-12-15 12:35:00) [56]
> что же мне указывать, если мне все поля нужны? перечислять
> их все через запятую?
Ленивым не место в программирование.
Anatoly Podgoretsky (2010-12-15 12:34:00) [57]
> но, если
> TDateTime(Trunc( datetimepicker.date))
Ты зачем так делаешь, вроде бы достаточно грамотный программист.
megavoid (2010-12-15 12:29:00) [58]не, не то же самое. Qry: Parameter 'ddate' not found - логично, ведь
for j := 0 to qry.Params.Count-1 do showmessage(qry.params[i].Name + qry.params[i].value); // !!
ничего не выдаёт
но запрос-то работает!
megavoid (2010-12-15 12:27:00) [59]Добавил Qry.ParamByName('ddate').asDateTime; чтобы совсем уж точно. То же самое.
Ega23 (2010-12-15 12:23:00) [60]
> fd2sql (c) Белов Владимир
Укуси меня пчела...
О сколько раз твердили миру - используйте уже параметры.
З.Ы. Мне страшно ходить в кинотеатры.