Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

[D2010] Магия мыши в TSQLQuery + DateTimePicker [MySQL]


Страницы:   1 2 3 4 5

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 14:41:00) [21]

> sniknik  (15.12.2010 14:29:04)  [64]

А я и не рекомендовал, просто указал, что и это надежный метод при
правильном написание, а не при SELECT *
В контексте необходимости явного указания полей.


Ega23   (2010-12-15 14:40:00) [22]


> Не зарекаюсь, но с 99.999% вероятностью на протяжении жизни
> этого проекта админ не будет трогать бд.


А ты не допускаешь мысли, что кроме данного проекта ты в своей жизни ещё и другими будешь заниматься? Где данное разделение будет в порядке вещей?
Учись писать правильно с самого начала. Тебе не вредные советы дают, тут люди не один такой "кинозал" написали, а по десятку (если не больше).


Anatoly Podgoretsky   (2010-12-15 14:39:00) [23]

> sniknik  (15.12.2010 14:28:03)  [63]

На stringgrid можно много выиграть, очень медленный компонент.


Anatoly Podgoretsky   (2010-12-15 14:38:00) [24]

> megavoid  (15.12.2010 14:27:02)  [62]

Ты даже не преставляешь как SQL работает, да именно обязан.
Какой "Ega23 придёт и порядок полей поменяет" тебе порядок полей в твоей
программе поменяет, окстись.


Ega23   (2010-12-15 14:38:00) [25]


> Ага, укажу я поля в запросе явно, а SQL обязан мне их в
> таком же порядке вернуть?


Естественно.
Также, как и то, что сервер тебе произвольный порядок самих записей может выдать, если ты явно Order By не указал. На одинаковом запросе.


> + главный "тормоз" будет/есть не в нем а в стринггриде.
> и даже если ему поставить "дизебле" (там как то по другому
> называется)


По всей видимости StringGrid1.Rows.BeginUpdate\EndUpdate
проверять лениво.


megavoid   (2010-12-15 14:32:00) [26]

>>Кроме того все ты не проконтролируешь, на нормальных фирмах это разделено между разными людьми, и первому человеку совсем не обязательно знать, что админ добавил blob поле.
Не зарекаюсь, но с 99.999% вероятностью на протяжении жизни этого проекта админ не будет трогать бд.


Ega23   (2010-12-15 14:29:00) [27]


> В данном конкретном случае администратор БД управляется
> мной же, и я просто не пропущу большой блоб. Когда это писалось,
>  я закладывался на полный контроль всего комплекса со стороны
> меня, что и позволяет мне достаточно вольно писать мой говнокод,
>  точно помня что, где и как расположено.


Дык нету у тебя полного контроля при *, пойми. Полный контроль - когда ты чётко выбираешь именно те поля, которые тебе нужны. В том самом порядке, который тебе нужен.


> Экономия, всё верно выше подметили. Над завести много датасетов
> - подумаю.


Ты не на том экономишь. Если аналогию провести, то ты сейчас экономишь на мусорных пакетах, выбрасывая всё что есть в один, а потом на мусорке его разгребать и по разным контейнерам складывать: туда - пищевые отходы, туда - стекло всякое и т.д.
Впрочем, это был ещё один совет. :)))


> Прописал disable/enable. На глазок по скорости выполнения
> то же самое, но глазок не профайлер, вечером замерю без
> и с disablecontrols.

Может и не дать, тут очень многое зависит непосредственно от компонента. Надо реализацию смотреть. Но в целом - надо писать, это правило хорошего тона.


> Там только ради WM_PAINT. Не 5, а 2-3 секунды :) WinSight
> у меня частенько открыт. Ну, даже если придёт LBUTTONDOWN
> или CLOSE - как это собьёт мне Query?


А ты возьми, зацепи окно мышкой и не отпускай. Потаскай его по экрану.

Screen.Cursor := crSQLWait;
try
 with DataSet do
 begin
    Open;
    ........
 end;
finally
 Screen.Cursor := crDefault;
end;


sniknik   (2010-12-15 14:29:00) [28]

> Ага, укажу я поля в запросе явно, а SQL обязан мне их в таком же порядке вернуть?
да.
хотя это и "всплыло" от не рекомендованного тут метода.


sniknik   (2010-12-15 14:28:00) [29]

> Куда "за"? Оно потому и внутри цикла, что я получаю данные из полей в цикле.
за цикл, и не получение данных, а определение по имени. блин.
что так сложно понять, до цикла определить поле и запомнить его в переменную, в цикле использовать ее.

> Прописал disable/enable. На глазок по скорости выполнения то же самое, но глазок не профайлер, вечером замерю без и с disablecontrols.
на ста записях заметно не будет, вот сто тысяч... другое дело. + главный "тормоз" будет/есть не в нем а в стринггриде. и даже если ему поставить "дизебле" (там как то по другому называется) на обновления, это тоже будет мелочь по сравнению с тем как он сам по себе тормозит. "из принципа" (по логике с которой сделан)


megavoid   (2010-12-15 14:27:00) [30]

> Уверенность надо обретать в явном указание полей, а тогда
> можно и Fields[i]

Ага, укажу я поля в запросе явно, а SQL обязан мне их в таком же порядке вернуть? Я уж лучше через .FieldByName. А то и вообще Ega23 придёт и порядок полей поменяет, а с fieldbyname мне это фиолетово.


Anatoly Podgoretsky   (2010-12-15 14:26:00) [31]

> megavoid  (15.12.2010 14:16:57)  [57]

" и я просто не пропущу большой блоб."

Не зарекайся. Кроме того все ты не проконтролируешь, на нормальных фирмах
это разделено между разными людьми, и первому человеку совсем не обязательно
знать, что админ добавил blob поле. Не его это дело, его дело писать
правильные запросы, а не лениться. Молчу уж про параметры и оптимизатор.


Anatoly Podgoretsky   (2010-12-15 14:22:00) [32]

> Ega23  (15.12.2010 13:54:53)  [53]

"Fields[Index] - это только если ты строго уверен, что НД пришёл в строго
определённом порядке полей."

Уверенность надо обретать в явном указание полей, а тогда можно и Fields[i]


megavoid   (2010-12-15 14:19:00) [33]

> > вынести "за" и все дела
Куда "за"? Оно потому и внутри цикла, что я получаю данные из полей в цикле.


Anatoly Podgoretsky   (2010-12-15 14:19:00) [34]

> Ega23  (15.12.2010 13:54:53)  [53]

Ты где такие маленькие битмапы нашел.


megavoid   (2010-12-15 14:16:00) [35]


> Вот теперь я, как администратор БД, беру и меняю порядок
> полей в таблице. Или, например, добавлю в данную таблицу
> блоб-поле, в которой битмап для каждой записи будет лежать.
>  Метра так на 2.

В данном конкретном случае администратор БД управляется мной же, и я просто не пропущу большой блоб. Когда это писалось, я закладывался на полный контроль всего комплекса со стороны меня, что и позволяет мне достаточно вольно писать мой говнокод, точно помня что, где и как расположено.


> скажи, а зачем такой изврат нужен? Ну, в смысле, один DataSet
> на всё приложение?

Экономия, всё верно выше подметили. Над завести много датасетов - подумаю.


> Простейшая операция disable|enable controls дала прирост
> производительности то ли в 30 раз, то ли в 70.

Прописал disable/enable. На глазок по скорости выполнения то же самое, но глазок не профайлер, вечером замерю без и с disablecontrols.


> Application.ProcessMessages

Там только ради WM_PAINT. Не 5, а 2-3 секунды :) WinSight у меня частенько открыт. Ну, даже если придёт LBUTTONDOWN или CLOSE - как это собьёт мне Query? Если пришлют DESTROY - ну тут и так понятно что хана, никакой квери уже нафиг не нужен будет.

ЗЫ. А кресло у меня большое-большое, ага :) А программирование мне больше по душе :)


sniknik   (2010-12-15 14:14:00) [36]

> Поясни "в третьих определение по имени поля внутри цикла"
> вынести "за" и все дела


Ega23   (2010-12-15 14:11:00) [37]


> не выдумывай отсебятины... Fields[Index] я сам нигде не
> использую и другим не советую.


Тогда я тебя не понял. Поясни "в третьих определение по имени поля внутри цикла"


sniknik   (2010-12-15 14:09:00) [38]

> Вот тут я со sniknik не согласен. FieldByName - в целом более правильное обращение. Fields[Index] - это только если ты строго уверен
не выдумывай отсебятины... Fields[Index] я сам нигде не использую и другим не советую.
> в третьих определение по имени поля внутри цикла
где тут Fields[Index]? здесь про "внутри цикла", вынести "за" и все дела, а не менять на что то самопридуманное.


Ega23   (2010-12-15 13:54:00) [39]


> И если на следующий день заказчик захочет добавить ещё одно
> поле в базу, придётся ходить и везде его приписывать? В
> других запросах, где мне требуются только отдельные поля,
>  я указываю их. Если нужны все - ставлю *.


Вот теперь я, как администратор БД, беру и меняю порядок полей в таблице. Или, например, добавлю в данную таблицу блоб-поле, в которой битмап для каждой записи будет лежать. Метра так на 2.
И теперь ты по своей * будешь тащить на каждый чих по 100 записей дополнительно 200 мегабайт картинок.
Это первое.
Второе: а тебе и так и так придётся переписывать. Добавлять fieldByName и заносить его в определённый столбец твоего StringGrid.


>  это будет мне очень неудобно - sql запрос req конструируется
> разный, в разных местах, с разными параметрами


скажи, а зачем такой изврат нужен? Ну, в смысле, один DataSet на всё приложение? Заведи себе их столько, сколько нужно. Аккуратно пропиши параметры. Выстави Prepared (скомпилируй заранее).
Получишь афигенный выигрыш на скорости, проверено неоднократно.


> > в третьих определение по имени поля внутри цикла
> это из области фильмов ужасов, ага, но - работает


Вот тут я со sniknik не согласен. FieldByName - в целом более правильное обращение. Fields[Index] - это только если ты строго уверен, что НД пришёл в строго определённом порядке полей. Что сильно повышает неустойчивость в случае, если работаешь с хранимой процедурой, а её код может кто-то модифицировать.


> нет. юзеры всё равно ничего не успеют сделать, пока получаем
> данные
> сильно подозреваю, что тоже из ужастиков


Зря подозреваешь. Смотри код TDataSet. Года 2.5 -3 назад аккурат на этом форуме я вопрос поднимал. Простейшая операция disable|enable controls дала прирост производительности то ли в 30 раз, то ли в 70.


>  Но извне, пока работает FillGrid, никаких сообщений не
> придёт - всё однопоточное.


Да ну? Ты, видать, плохо разбираешься, что такое Application.ProcessMessages.
простой пример.
У тебя, запрос, который выполняется 5 секунд (это только Open). За эти 5 секунд ты наделал кучу всякой разной фигни мышкой. Что будет - предлагаю тебе самому на чистом проекте испытать.


Anatoly Podgoretsky   (2010-12-15 13:48:00) [40]

> megavoid  (15.12.2010 13:29:50)  [50]

"И если на следующий день заказчик захочет добавить ещё одно поле в базу,
придётся ходить и везде его приписывать?"

Я уже говорил, что ленивым нечего делать в программирование. Тебе надо в
менеджеры и чтобы кресло пошире.


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо