0.9.22 + MySQLlib.dll v 4.1 + GROUP BY

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

0.9.22 + MySQLlib.dll v 4.1 + GROUP BY

Сообщение Smoky555 » 03.07.2007 11:08:52

Здравствуйте всем
Вот такая у меня беда случилась.
Использую Lazarus 0.9.22 + sqllib.dll от MySQL 4.1 (это на рабочей машине, под winxp pro sp2).
На сервере - ASPLinux11.2 + MySQL Server v 4.1.20

В моем приложении есть куча запросов к БД, причем они только на чтение.
Запросы типа
Код: Выделить всё
select customer_id from customers where( group_id=3)
работают на ура.
но вот когда понадобилось сделать запрос с использованием группировки - вот тут и вылезло ... зло.
вот кусок кода приложения:
Код: Выделить всё
      SQLQuery3.Close;
      SQLQuery3.SQL.Clear;
      SQLQuery3.SQL.Append('SELECT');
      SQLQuery3.SQL.Append('flows.dst_addr,');
      SQLQuery3.SQL.Append('SUM(d_octets) AS field1');
      SQLQuery3.SQL.Append('FROM');
      SQLQuery3.SQL.Append('flows');
      SQLQuery3.SQL.Append('WHERE');
      SQLQuery3.SQL.Append('(src_addr = 12345) AND');
      SQLQuery3.SQL.Append('(`timestamp` >= 20070703000000) AND');
      SQLQuery3.SQL.Append('(`timestamp` <= 20070703235959)');
      SQLQuery3.SQL.Append('GROUP BY');
      SQLQuery3.SQL.Append('flows.dst_addr');
      SQLQuery3.SQL.Append('ORDER BY');
      SQLQuery3.SQL.Append('field1');
      ShowMessage(SQLQuery3.SQL.Text);
      SQLQuery3.ExecSQL;                 

не смотрите на громоздкость - просто уже перепробовал все возможные варианты. Вобчем этот код при исполнении дает ошибку. Причем ругается на GROUP.
Посмотрел в логах сервера и вот что вижу:
если по ShowMessage(SQLQuery3.SQL.Text); вижу нормальный запрос, без ничего лишнего, т.е.
Код: Выделить всё
SELECT
flows.dst_addr,
SUM(d_octets) AS field1
FROM
flows
WHERE
(src_addr = 12345) AND
(`timestamp` >= 20070703000000) AND
(`timestamp` <= 20070703235959)
GROUP BY
flows.dst_addr
ORDER BY
field1

то на сервер он приходит в таком виде :
Код: Выделить всё
SELECT
flows.dst_addr,
SUM(d_octets) AS field1
FROM(
flows
WHERE
(src_addr = 12345) AND
(`timestamp` >= 20070703000000) AND
(`timestamp` <= 20070703235959)
GROUP BY
flows.dst_addr
)ORDER BY
field1

Откуда появляются лишние скобки после FROM и перед ORDER ???
что их туда добавляет? Лазарус, библиотека клиента или сам сервер?
Как от этого можно избавиться?
Smoky555
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.03.2007 15:35:33
Откуда: Volgograd

Сообщение shade » 03.07.2007 13:47:00

Может баг?..
А использовать SQLQuery3.SQL.Text := 'SELECT ...' религия запрещает?
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение Smoky555 » 03.07.2007 13:49:27

shade писал(а):Может баг?..
А использовать SQLQuery3.SQL.Text := 'SELECT ...' религия запрещает?

чесно?
вариантов 5 испробовал, в том числе и этот.
я же говорю, по showmessage - запрос идеальный, копирую его в EMS SQL Manager for MySQL - обрабатывается идеально, а вот что по SQLQuery.Open что по SQLQuery.Execute - одна и та же ошибка, одни и те же изменения ...
Smoky555
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.03.2007 15:35:33
Откуда: Volgograd

Сообщение shade » 03.07.2007 13:57:16

Напиши небольшой пример содержащий только этот код, проверь, если ошибка повторяется то выкладывай сюда, до вечера проверю на своей машине (у меня тож ASPLinux 11.2)
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение Smoky555 » 03.07.2007 14:34:29

shade писал(а):Напиши небольшой пример содержащий только этот код, проверь, если ошибка повторяется то выкладывай сюда, до вечера проверю на своей машине (у меня тож ASPLinux 11.2)

Дело тут не коде проекта.
ошибка заключается в том, что кто-то или что-то в цепочки от SQLQuery до логов Mysql сервера заключает все, что стоит после WHERE до ORDER в круглые скобки.
Причем убирал из этого запроса всю WHERE - запрос работает, как только появляется WHERE с любым количеством условий - тут же команда GROUP попадает в эти скобки, становясь одним из условий для WHERE - естественно тут же появляется ошибка.
Даже простой запрос типа
Код: Выделить всё
SELECT * FROM flows WHERE src_addr = 12345

превращается на сервере в
Код: Выделить всё
SELECT * FROM flows WHERE( src_addr = 12345)

так что тут не в проекте дело, а либо в каких-то настройках, либо еще где-то ...
но вот где ?!
Smoky555
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.03.2007 15:35:33
Откуда: Volgograd

Сообщение Smoky555 » 03.07.2007 15:15:53

все, проблема решилась ...
гррррррр :evil:

вобщем так, даже если в свойствах SQLQuery установлено что Parse := false, все равно при выполнении запроса весь запрос "парсится", а в парсере он проверяется на команду "ORDER" а не "GROUP"
( lazarus->fpc->2.0.4->source->fcl->db->sqldb->sqldb.pp - строки начиная с 792 процедура TSQLQuery.SQLParser)
так вот чтоб парсер не включался когда не надо, необходимо перед самым ExecSQL или Open устанавливать этот параметр вручную, жестко, т.е.
Код: Выделить всё
SQLQuery3.ParseSQL := false;

и все, тогда запрос обрабатывается без ошибок, как, в принципе, и должно быть.

Надеюсь это мое решение поможет кому-нибудь ;)

Удачи всем в кодонаписании :)
Smoky555
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.03.2007 15:35:33
Откуда: Volgograd

Сообщение shade » 03.07.2007 16:58:46

В любом случае, если парсинг идет не правильно об этом стоит сообщить в багтреккер, чтобы другие не мучались :wink:
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 109

Рейтинг@Mail.ru