С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 04.12.2018
Сообщений: 5
1
MySQL

Ошибка сортировки в Delphi 64bit поля Decimal

04.12.2018, 19:37. Показов 1064. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет! Спецы Delphi и MySQL нужна ваша помощь)

Имеется: Delphi XE8 + dbExpress + старенький сервер Mysql v5.0.45 win32 + база MyISAM и в таблице поле DECIMAL(5,2) со знаком.
Таблица храниться как:
Charset cp1251
Collation: cp1251_general_ci

В Delphi использую TSQLConnection + TDataSource + TSimpleDataSet
TSQLConnection в параметрах прописал ServerCharSet cp1251

Из таблицы делается простой Select и сортировка по полю DECIMAL. Пока программа компилировалась как 32-разрядная, все работало. Однако пришлось переделать ее под 64 бита и сразу же вылезла неприятная ошибка - перестала работать сортировка по этому полю. Если программу снова пересобрать под 32 - сортировка работает.

То есть ошибка только в 64 разрядной программе. Опытным путем было установлено, что положительные числа сортирует правильно:
2.25
2.5
2.75
Однако числа со знаком отказываются сортироваться
-0.25
0.25
-0.5
0.5
и тд

Тип DECIMAL(5,2) выбрал потому, что очень важна точность. Число 2.75 так и должно храниться в базе и не искажаться. На данный момет я не понимаю, где случается засада. Тип DECIMAL(5,2) хранится как строка, переведя программу под 64 разряда я изменил ее представление в программе, но не ясно где проблема:
- TSQLConnection + TDataSource + TSimpleDataSet?
- проблема во взаимодействии клиента с сервером, кодировки, правила сравнения для кодировки?

Можно все порешать переведя поле во FLOAT, но я переживаю из-за потери точности, хотелось бы решить проблему с сортировкой DECIMAL
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Блог
04.12.2018, 19:37
Ответы с готовыми решениями:

Ошибка Cannot convert from 'ref decimal' to 'ref decimal?
Здравствуйте подскажите пожалуйста почему в строке ...

Хранимая процедура сортировки числового поля для сортировки по алфавиту
В таблице есть поле Name , в котором, собственно, и хранятся типы товаров, и есть поле Ordinal c...

Валидация поля decimal на стороне клиента без влияния региональных настроек
Доброго времени суток уважаемые форумчане, подскажите пожалуйста с таким вопросом: есть модель и...

Не работает запрос с одинаковыми типами данных c# decimal, SQL Server Decimal(18,2)
Здравствуйте, не понимаю почему не проходит запрос на бд, с одинаковыми типами данныхDecimal(18,2)...

9
5868 / 4596 / 1448
Регистрация: 14.04.2014
Сообщений: 20,393
Записей в блоге: 20
04.12.2018, 20:56 2
а как сортировка-то задается?
через ORDER BY ?
0
0 / 0 / 0
Регистрация: 04.12.2018
Сообщений: 5
04.12.2018, 21:12  [ТС] 3
Сорри, самое главное забыл)
Да, запрос совсем простой:
select * table order by field
field - DECIMAL(5,2) со знаком
В 32-ух разрядной программе все работало, в 64 разрядной выдает такое:
0
-0.25
0.25
-0.5
-0.75
-1
То есть перестает знак учитывать. Я больше склоняюсь к ошибке при взаимодействии клиента и сервера, только не ясно куда копать.
0
Эксперт Pascal/Delphi
1135 / 616 / 129
Регистрация: 13.02.2009
Сообщений: 3,566
04.12.2018, 22:11 4
Цитата Сообщение от DimonRX Посмотреть сообщение
только не ясно куда копать.
Подключить к серверу без Delphi и проверять запрос
0
0 / 0 / 0
Регистрация: 04.12.2018
Сообщений: 5
04.12.2018, 22:29  [ТС] 5
Заюзал MySQL Query Browser, запрос отработал корректно. Но этот MySQL Query Browser 32-ух разрядный. Если я свою прогу сейчас перекомпилю в 32-разряда - она тоже снова заработает. Через какую 64-ех разрядную программу протестить можно? Или все таки переехать на MySQL версии 5.1 64-разрядную и там будут утилиты тоже 64 бит?
0
Эксперт Pascal/Delphi
1135 / 616 / 129
Регистрация: 13.02.2009
Сообщений: 3,566
04.12.2018, 22:39 6
Цитата Сообщение от DimonRX Посмотреть сообщение
Заюзал MySQL Query Browser, запрос отработал корректно. Но этот MySQL Query Browser 32-ух разрядный
Проверять надо из 64 битного ПК - из mysql workbench 64-ух разрядный. https://www.mysql.com/products/workbench/
0
0 / 0 / 0
Регистрация: 04.12.2018
Сообщений: 5
04.12.2018, 22:42  [ТС] 7
ПК 64 битный, MySQL Query Browser 64-ух разрядный попрубую поискать, спасибо за наводку

Стоит ли делать такое?
1. Проапгрейдить мускул до mysql-essential-5.1.72-winx64.msi Сервер будет тоже 64 бит, как и моя программа
2. Переконвертировать всю базу в utf-8. Думаю сделать через dump, руками поменять кодирувку и collation и снова залить
3. Все взаимодействие клиент-сервер перевести на utf-8
character_set_client - utf8
character_set_connection - utf8
character_set_database - utf8
character_set_results - utf8
character_set_server - utf8
character_set_system - utf8
collation_connection - utf8_general_ci
collation_database - utf8_general_ci
collation_server - utf8_general_ci
0
Эксперт Pascal/Delphi
1135 / 616 / 129
Регистрация: 13.02.2009
Сообщений: 3,566
04.12.2018, 22:48 8
Цитата Сообщение от DimonRX Посмотреть сообщение
MySQL Query Browser 64-ух разрядный попрубую поискать,
Через MySQL Workbench 8.0.13 проверяй https://dev.mysql.com/downloads/workbench/ кодировка лучше на utf8 да

Добавлено через 1 минуту
и ещё лучше если будите подключить через MyDAC
0
5580 / 4430 / 1080
Регистрация: 29.08.2013
Сообщений: 27,707
Записей в блоге: 3
05.12.2018, 07:52 9
а такое не поможет?

DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]

``Неупакованное'' число с плавающей точкой. Ведет себя подобно столбцу CHAR, содержащему цифровое значение. Термин ``неупакованное'' означает, что число хранится в виде строки и при этом для каждого десятичного знака используется один символ. Разделительный знак десятичных разрядов, а также знак ‘-’ для отрицательных чисел не учитываются в M (но место для них зарезервировано). Если атрибут D равен 0, величины будут представлены без десятичного знака, т.е. без дробной части. Максимальный интервал значений типа DECIMAL тот же, что и для типа DOUBLE, но действительный интервал для конкретного столбца DECIMAL может быть ограничен выбором значений атрибутов M и D. Если указан атрибут UNSIGNED, отрицательные значения недопустимы. Если атрибут D не указан, его значение по умолчанию равно 0. Если не указан M, его значение по умолчанию равно 10. В более ранних, чем MySQL 3.23, версиях аргумент M должен содержать в себе место для знака числа и десятичного знака.
из справки по типу DECIMAL
0
0 / 0 / 0
Регистрация: 04.12.2018
Сообщений: 5
05.12.2018, 13:10  [ТС] 10
MySQL Workbench 8.0.13 с моим сервером работать отказался, поставил MySQL Workbench 6.2 64bits, он при старте ругается, что нужен мускул хотя бы 5.1, но запускается. Запрос отработал корректно. То есть дело в программе.

В Delphi обнаружил FireDAC, кинул на форму FDConnection + FDQuery и запрос тоже работает, то есть дело в dbExpress.

Выбросил TSimpleDataSet, взял просто TSQLQuery и он тоже отработал норм. Проблема локализовалась в TSimpleDataSet. Он кеширует данные в памяти, создает двунаправленный курсор. Когда я перевел прогу под 64 бита, он стал как то по другому кешировать данные и вот вылезла проблема.

qwertehok, похоже действительно в этом проблема. Потому что вот еще из справки, но уже для мускула 5.5:
Values for DECIMAL columns are stored using a binary format that packs nine decimal digits into 4 bytes. The storage requirements for the integer and fractional parts of each value are determined separately. Each multiple of nine digits requires 4 bytes, and any remaining digits left over require some fraction of 4 bytes. The storage required for remaining digits is given by the following table.
То есть получается, в версии мускула 5.5 DECIMAL теперь хранится не как строка, а как 2 числа. А я все проблему в сравнении строк ищу))
У меня сервер старый 5.0, а Delphi и dbExpress относительно новые
Delphi XE8 + Dbxmys.dll 22.0.19908.869
Видимо драйвер dbExpress слишком новый и не понимает старый мускул.

Может можно нарыть где в инете старый Dbxmys.dll, который был под сервер 5.1 написан и пока его заюзать? А потом уже не спеша проапгрейдить мускул до 5 версий

Добавлено через 7 минут
Проапгрейдить мускул до 5.5 версии
0
05.12.2018, 13:10
cpp_developer
Эксперт
20123 / 5690 / 417
Регистрация: 09.04.2010
Сообщений: 12,546
Блог
05.12.2018, 13:10
Помогаю со студенческими работами здесь

Delphi ошибка синтаксиса при определение поля
Помогите в чём проблема создаю таблицу: form1.ADOQuery1.SQL.Add('Create table '+Edit1.Text+'(Nam...

Настройка IPv6 (Debian 7 64bit/CentOS 6 64bit) на VPS
На VPS (Debian 7 64bit / CentOS 6 64bit), к основному IPv4, провайдер выдает блок IPv6. Но в ОС...

OpenGL и невидимый Bitmap: не всякая поверхность строится под Delphi XE2 64bit
В соседних ветках описывал свои мучения с выводом графики OpenGL на невидимый Битмап. Проблемы...

Condition Zero 1.2 на Win7 64bit. Ошибка file read failure
Поставил Condition Zero 1.2 на Windows 7 64bit. Добился чтобы работали миссии (поставил режим...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru