04.03.2009, 19:07 | #1 |
Участник
|
Сортировка и сравнение строк
Есть 2 записи в таблице с текстовым кодом
".б" "-а" Если делать выборку с сортировкой по коду то порядок выборку получается такой 1 - ".б" 2 - "-а" Если же это временная таблица, то тот же запрос inventtable it; ; it.setTmp(); it.ItemId = "1"; it.ItemName = ".б"; it.doInsert(); it.ItemId = "2"; it.ItemName = "-а"; it.doInsert(); while select it order by itemName { info(strfmt("%1 / %2", it.ItemId, it.ItemName)); } - порядок другой 1 - "-а" 2 - ".б" т.е. упорядочение строк на СУБД и в x++ может быть разное. Это что у всех так? А то у меня из-за такого конфуза алгоритм поломался... (MBS Axapta 3.0 Sp4 Build#11.0) MSSQL 2005 |
|
04.03.2009, 20:36 | #2 |
Moderator
|
Я думаю это зависит от collation на сервере БД.
Какой у вас на MS SQL выставлен вы посмотреть можете. А какой Axapta использует для временных таблиц можно экспериментальным путем определить. |
|
04.03.2009, 23:52 | #3 |
MCITP
|
100пудово именно так. Временные таблицы Аксапта в файлике ОС хранит и сортирует соответсвенно по своему, по параметрам в винде...
Запрос же к БД обрабатывается СУБД и сортируется по соответсвующим настройкам БД.
__________________
Zhirenkov Vitaly |
|
05.03.2009, 05:39 | #4 |
Участник
|
На сервере БД стоит в соответсвии с рекомендациями документа по администрированию.
Возможно ли как то настройки упорядочивания эти синхронизировать? Просто была необходимость ускорить работу отчета и я сделал это путем генерации нескольких больших запросов отсортировав по ключевому полю. Потом паралельно выбирая записи синхронизировался по этому ключевому полю. Синхронизация ключей предполагает сравнение их уже в коде х++. И как оказалось результат сравнения не соответсвует сортировке в БД... И встал вопрос как проще извернуться чтобы не потерять полученую эффективность, но устранить полученные косяки. |
|
05.03.2009, 07:42 | #5 |
MCTS
|
У меня ax3 sp5 kr3 Oracle 10g
Оба селекта работаю одинаково. Думал, может вы точку (англ/рус) перепутали. Попробовал сделать так. Но даже с разными знаками вывод идет в одинаковом порядке. |
|
05.03.2009, 08:13 | #6 |
Программатор
|
Может дело в выравнивании? Посмотрите выравнивание в InventTable.itemname и поле в временной табле.
|
|
05.03.2009, 11:35 | #7 |
MCITP
|
Цитата:
С Ораклом ситуация чуть другая, у вас наверняка ж стоит на БД NLS_COMP в значении "BINARY" (ну либо пустое, по умолчанию = BINARY). Это значит, что все сравнения и сортировки будут бинарные, по коду символов в кодировке. Насколько я понимаю, именно так сортируются и временные таблицы в ОС Аксаптой. Хотя теоретически это тоже может зависеть от кодировки, которую использует БД. Если вы найдёте такую кодировку, где символ "-" имеет код больше чем ".", и используете её в БД, то будет тот же эффект... (обычно код "-"= 45, код "."= 46) 2 Perc: посмотрите на сервере БД какие коды у этих символов и какие у вас кодировки и колэйшыны стоят - в студию. PS В случае же когда на сервере БД используется "лингвистическая" сортировка, там вообще может быть всё что угодно, в этом я не силён.
__________________
Zhirenkov Vitaly |
|
05.03.2009, 11:44 | #8 |
MCTS
|
Цитата:
С Ораклом ситуация чуть другая, у вас наверняка ж стоит на БД NLS_COMP в значении "BINARY"
ZVV, пользуясь случаем, задам вам один вопрос, заранее спасибо. У меня щас в базе следующие настройки: Цитата:
Сообщение (13:44:37)
NLS_CHARACTERSET = CL8MSWIN1251 NLS_COMP = BINARY NLS_LENGTH_SEMANTICS = BYTE NLS_NCHAR_CHARACTERSET = AL16UTF16 Насколько праильны настройки сейчас? И при переносе базы, правильно ли все отработает при таких же настройках на новом сервере? |
|
|
За это сообщение автора поблагодарили: Logger (1). |
05.03.2009, 12:18 | #9 |
MCITP
|
Цитата:
Сначала создадите БД на линуксе, это не сильно принципиально с какой основной кодировкой, главное, чтоб она поддерживала все необходимые символы, которые у вас сейчас используются. А при процедуре экспорта-импорта все данные будут перекодированы в новую кодировку. Теоретически можно оставить и CL8MSWIN1251, я не в курсе о проблемах с этой кодировкой на Линуксе. (но это, конечно, не гарантирует что их нет, это лучше уточнить в техподдержке, если у вас есть ) Если же вы в новой базе поставите несовместимую кодировку, то при перекачке часть данных потеряется, будут "вопросики" вместо русских букв и ещё части символов... Судя по документации для Русского языка выбор у Вас следующий: CL8ISO8859P5, CL8KOI8R, CL8MSWIN1251, AL16UTF16, AL32UTF8, UTF8 (последние 3 - это юникодные кодировки) Для других языков смотрите Oracle® Database Globalization Support Guide С остальными параметрами вроде проблем быть вообще не должно... В любом случае сначала протестируйте переход и проверьте что всё ОК!
__________________
Zhirenkov Vitaly |
|
|
За это сообщение автора поблагодарили: Eldar9x (2). |
05.03.2009, 12:21 | #10 |
MCTS
|
Цитата:
А при процедуре экспорта-импорта все данные будут перекодированы в новую кодировку.
|
|
05.03.2009, 19:05 | #11 |
Участник
|
Цитата:
Как правильно смотреть коды символов на сервере БД не знаю, но запрос: select field1, ASCII(SUBSTRING(field1, 1, 1)), ASCII(SUBSTRING(field1, 2, 1)), UNICODE(SUBSTRING(field1, 1, 1)), UNICODE(SUBSTRING(field1, 2, 1)) from table1 order by field1 asc дает результат: .б 46 225 46 1073 -а 45 224 45 1072 |
|
10.03.2009, 10:55 | #12 |
Участник
|
Цитата:
PHP код:
Если сравниваемые символы - это не буквы и не цифры, то результат заранее предсказать сложно. Если есть возможность, то лучше синхронизировать коды не сравнивая по принципу "больше/меньше", а сравнивая по принципу "не равно". Например, у нас Ax2.5SP3 и MS SQL 2005 Collation SQL_Latin1_General_CP1251_CI_AS. При такой сортировке, символ дефиса (тире) оказывается меньше любого другого символа. Даже меньше пустой строки (!) Поэтому, если в Axapta написать запрос вида X++: select MyTab where MyTab.MyField X++: select * from MyTab where MyTab.MyField > '' А вот если написать X++: select MyTab where MyTab.MyField != "" X++: select * from MyTab where MyTab.MyField <> '' Другой вариант - это делать выборку на сервере, а потом перегонять ее во временную таблицу на клиенте для корректной сортировки. |
|
|
За это сообщение автора поблагодарили: Logger (5), tricky (1). |
25.08.2010, 19:20 | #13 |
Участник
|
Цитата:
Опасный баг. Это же может вылезти в куче мест. Все таки странно каким чудом дефис оказался меньше пустой строки. По логике не должно так быть. Это скорее всего бага в БД. Интересно а что будет, если в коде Аксапты вместо X++: select MyTab where MyTab.MyField X++: select MyTab where MyTab.MyField>'-' |
|
25.08.2010, 19:47 | #14 |
Участник
|
Пробовали, конечно. В последнем сообщении приведен тестовый пример, как можно посмотреть при каком Collation какой порядок сортировки будет. Например, при Cyrillic_General_CI_AS все "как положено". Пустое значение и пробел считаются самыми маленьким символами.
Бросается в глаза именно положение пустого значения и пробела, которые оказываются больше ряда символов (одиночный апостроф, дефис, длинные тире и др.). Ну, это вряд ли. Типичная ситуация, когда это вылезает - это сравнение на пустоту. Мало кому в голову приходит сравнивать символьные строки на больше/меньше. Более того, должно быть не просто сравнение на пустоту, но и содержимое поля должно начинаться с символа дефиса. Достаточно редкая ситуация Собственно, именно поэтому и не поменяли Collation на сервере. Просто не возникает проблемных ситуаций по данной причине. А там, где это надо учитывать (ну в очень специфических ситуациях) делаем специальный обход. Цитата:
Так понятно, что будет. Если пустое значение больше, чем дефис, то в выборку попадут все поля с пустым значением поля Последний раз редактировалось Владимир Максимов; 25.08.2010 в 19:58. |
|
25.08.2010, 20:06 | #15 |
Участник
|
Спасибо за информацию.
Цитата:
X++: select MyTab where MyTab.MyField И кстати, я считаю что для условия на пустоту/непустоту строкого поля правильнее писать X++: select MyTab where MyTab.MyField X++: select MyTab where MyTab.MyField != '' |
|