0.9.22 + MySQLlib.dll v 4.1 + GROUP BY

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

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

Ответить
Smoky555
незнакомец
Сообщения: 6
Зарегистрирован: 05.03.2007 14:35:33
Откуда: Volgograd
Контактная информация:

0.9.22 + MySQLlib.dll v 4.1 + GROUP BY

Сообщение Smoky555 »

Здравствуйте всем
Вот такая у меня беда случилась.
Использую 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 ???
что их туда добавляет? Лазарус, библиотека клиента или сам сервер?
Как от этого можно избавиться?
Аватара пользователя
shade
энтузиаст
Сообщения: 879
Зарегистрирован: 21.02.2006 19:15:48
Откуда: http://shamangrad.net/
Контактная информация:

Сообщение shade »

Может баг?..
А использовать SQLQuery3.SQL.Text := 'SELECT ...' религия запрещает?
Smoky555
незнакомец
Сообщения: 6
Зарегистрирован: 05.03.2007 14:35:33
Откуда: Volgograd
Контактная информация:

Сообщение Smoky555 »

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

чесно?
вариантов 5 испробовал, в том числе и этот.
я же говорю, по showmessage - запрос идеальный, копирую его в EMS SQL Manager for MySQL - обрабатывается идеально, а вот что по SQLQuery.Open что по SQLQuery.Execute - одна и та же ошибка, одни и те же изменения ...
Аватара пользователя
shade
энтузиаст
Сообщения: 879
Зарегистрирован: 21.02.2006 19:15:48
Откуда: http://shamangrad.net/
Контактная информация:

Сообщение shade »

Напиши небольшой пример содержащий только этот код, проверь, если ошибка повторяется то выкладывай сюда, до вечера проверю на своей машине (у меня тож ASPLinux 11.2)
Smoky555
незнакомец
Сообщения: 6
Зарегистрирован: 05.03.2007 14:35:33
Откуда: Volgograd
Контактная информация:

Сообщение Smoky555 »

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 14:35:33
Откуда: Volgograd
Контактная информация:

Сообщение Smoky555 »

все, проблема решилась ...
гррррррр :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;

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

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

Удачи всем в кодонаписании :)
Аватара пользователя
shade
энтузиаст
Сообщения: 879
Зарегистрирован: 21.02.2006 19:15:48
Откуда: http://shamangrad.net/
Контактная информация:

Сообщение shade »

В любом случае, если парсинг идет не правильно об этом стоит сообщить в багтреккер, чтобы другие не мучались :wink:
Ответить