AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 04.03.2009, 19:07   #1  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Сортировка и сравнение строк
Есть 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  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Я думаю это зависит от collation на сервере БД.
Какой у вас на MS SQL выставлен вы посмотреть можете.
А какой Axapta использует для временных таблиц можно экспериментальным путем определить.
Старый 04.03.2009, 23:52   #3  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Андре Посмотреть сообщение
Я думаю это зависит от collation на сервере БД.
100пудово именно так. Временные таблицы Аксапта в файлике ОС хранит и сортирует соответсвенно по своему, по параметрам в винде...
Запрос же к БД обрабатывается СУБД и сортируется по соответсвующим настройкам БД.
__________________
Zhirenkov Vitaly
Старый 05.03.2009, 05:39   #4  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
На сервере БД стоит в соответсвии с рекомендациями документа по администрированию.
Возможно ли как то настройки упорядочивания эти синхронизировать?
Просто была необходимость ускорить работу отчета и я сделал это путем генерации нескольких больших запросов отсортировав по ключевому полю. Потом паралельно выбирая записи синхронизировался по этому ключевому полю. Синхронизация ключей предполагает сравнение их уже в коде х++. И как оказалось результат сравнения не соответсвует сортировке в БД... И встал вопрос как проще извернуться чтобы не потерять полученую эффективность, но устранить полученные косяки.
Старый 05.03.2009, 07:42   #5  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
У меня ax3 sp5 kr3 Oracle 10g
Оба селекта работаю одинаково. Думал, может вы точку (англ/рус) перепутали. Попробовал сделать так. Но даже с разными знаками вывод идет в одинаковом порядке.
Старый 05.03.2009, 08:13   #6  
Sada is offline
Sada
Программатор
Аватар для Sada
 
1,450 / 153 (8) ++++++
Регистрация: 29.03.2005
Адрес: Толи Барнаул, толи Москва
Может дело в выравнивании? Посмотрите выравнивание в InventTable.itemname и поле в временной табле.
Старый 05.03.2009, 11:35   #7  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
У меня ax3 sp5 kr3 Oracle 10g
Оба селекта работаю одинаково. Думал, может вы точку (англ/рус) перепутали. Попробовал сделать так. Но даже с разными знаками вывод идет в одинаковом порядке.
В какой раскладке точку не вводи, код симола будет всё равно один и тот же - это не важно.
С Ораклом ситуация чуть другая, у вас наверняка ж стоит на БД NLS_COMP в значении "BINARY" (ну либо пустое, по умолчанию = BINARY). Это значит, что все сравнения и сортировки будут бинарные, по коду символов в кодировке. Насколько я понимаю, именно так сортируются и временные таблицы в ОС Аксаптой.
Хотя теоретически это тоже может зависеть от кодировки, которую использует БД.
Если вы найдёте такую кодировку, где символ "-" имеет код больше чем ".", и используете её в БД, то будет тот же эффект...
(обычно код "-"= 45, код "."= 46)

2 Perc: посмотрите на сервере БД какие коды у этих символов и какие у вас кодировки и колэйшыны стоят - в студию.

PS В случае же когда на сервере БД используется "лингвистическая" сортировка, там вообще может быть всё что угодно, в этом я не силён.
__________________
Zhirenkov Vitaly
Старый 05.03.2009, 11:44   #8  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
С Ораклом ситуация чуть другая, у вас наверняка ж стоит на БД NLS_COMP в значении "BINARY"
Да, именно так.
ZVV, пользуясь случаем, задам вам один вопрос, заранее спасибо.
У меня щас в базе следующие настройки:
Цитата:
Сообщение (13:44:37)
NLS_CHARACTERSET = CL8MSWIN1251
NLS_COMP = BINARY
NLS_LENGTH_SEMANTICS = BYTE
NLS_NCHAR_CHARACTERSET = AL16UTF16
Оракл стоит на win server 2003. В будущем планируется перенести базу на линукс.
Насколько праильны настройки сейчас? И при переносе базы, правильно ли все отработает при таких же настройках на новом сервере?
За это сообщение автора поблагодарили: Logger (1).
Старый 05.03.2009, 12:18   #9  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
Оракл стоит на win server 2003. В будущем планируется перенести базу на линукс.
Насколько праильны настройки сейчас? И при переносе базы, правильно ли все отработает при таких же настройках на новом сервере?
Вы же всё равно будете делать перенос Экспортом\Импортом?
Сначала создадите БД на линуксе, это не сильно принципиально с какой основной кодировкой, главное, чтоб она поддерживала все необходимые символы, которые у вас сейчас используются.
А при процедуре экспорта-импорта все данные будут перекодированы в новую кодировку. Теоретически можно оставить и CL8MSWIN1251, я не в курсе о проблемах с этой кодировкой на Линуксе. (но это, конечно, не гарантирует что их нет, это лучше уточнить в техподдержке, если у вас есть )
Если же вы в новой базе поставите несовместимую кодировку, то при перекачке часть данных потеряется, будут "вопросики" вместо русских букв и ещё части символов...

Судя по документации для Русского языка выбор у Вас следующий:
CL8ISO8859P5, CL8KOI8R, CL8MSWIN1251, AL16UTF16, AL32UTF8, UTF8
(последние 3 - это юникодные кодировки)
Для других языков смотрите Oracle® Database Globalization Support Guide

С остальными параметрами вроде проблем быть вообще не должно...

В любом случае сначала протестируйте переход и проверьте что всё ОК!
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: Eldar9x (2).
Старый 05.03.2009, 12:21   #10  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
А при процедуре экспорта-импорта все данные будут перекодированы в новую кодировку.
именно это и интересовало. Спасибо!
Старый 05.03.2009, 19:05   #11  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от ZVV Посмотреть сообщение
2 Perc: посмотрите на сервере БД какие коды у этих символов и какие у вас кодировки и колэйшыны стоят - в студию.
collation на сервере на БД и на таблице - Cyrillic_General_CI_AS.
Как правильно смотреть коды символов на сервере БД не знаю, но запрос:
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  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Perc Посмотреть сообщение
collation на сервере на БД и на таблице - Cyrillic_General_CI_AS.
Как правильно смотреть коды символов на сервере БД не знаю
Создаешь простую тестовую таблицу, наполняешь ее ASCII-кодами и сортируешь. Смотришь результат

PHP код:
if object_id('tempdb..#test'is not null drop table #test
-- Можно явно задавать Collation для символьных полей
-- если явно не указанто берется из настроек базы данных

create table 
#test (f1 int null, f2 varchar(1))

--create table #test (f1 int null, f2 varchar(1) COLLATE Cyrillic_General_CI_AS)
--create table #test (f1 int null, f2 varchar(1) COLLATE SQL_Latin1_General_CP1251_CI_AS)

declare @next int, @total int
set 
@total 255
set 
@next 0

-- Пустая строка
insert into 
#test values (null, '')

while (@next <= @total)
begin
    insert into 
#test values (@next, char(@next))
    
set @next = @next 1
end

select 
from #test order by f2 
Аналогично делаешь подобную временную таблицу в Axapta и смотришь, как оличается сортировка в Axapta от сортировки в MS SQL

Если сравниваемые символы - это не буквы и не цифры, то результат заранее предсказать сложно.

Если есть возможность, то лучше синхронизировать коды не сравнивая по принципу "больше/меньше", а сравнивая по принципу "не равно".

Например, у нас 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 > ''
но, поскольку дефис меньше (!) пустой строки, то если содержимое поля MyField начинается именно с дефиса, то эта запись не попадет в выборку (!)

А вот если написать

X++:
select MyTab where MyTab.MyField != ""
то на сервер уйдет запрос вида

X++:
select * from MyTab where MyTab.MyField <> ''
что корректно отработает с символом дефиса, поскольку он действительно отличен от пустой строки.


Другой вариант - это делать выборку на сервере, а потом перегонять ее во временную таблицу на клиенте для корректной сортировки.
За это сообщение автора поблагодарили: Logger (5), tricky (1).
Старый 25.08.2010, 19:20   #13  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Например, у нас Ax2.5SP3 и MS SQL 2005 Collation SQL_Latin1_General_CP1251_CI_AS. При такой сортировке, символ дефиса (тире) оказывается меньше любого другого символа. Даже меньше пустой строки (!)
Это сильно! А другой Collation не пробовали ?

Опасный баг. Это же может вылезти в куче мест. Все таки странно каким чудом дефис оказался меньше пустой строки. По логике не должно так быть. Это скорее всего бага в БД.

Интересно а что будет, если в коде Аксапты вместо
X++:
select MyTab where MyTab.MyField
поставить
X++:
select MyTab where MyTab.MyField>'-'
Старый 25.08.2010, 19:47   #14  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Logger Посмотреть сообщение
Это сильно! А другой Collation не пробовали ?
Пробовали, конечно. В последнем сообщении приведен тестовый пример, как можно посмотреть при каком Collation какой порядок сортировки будет. Например, при Cyrillic_General_CI_AS все "как положено". Пустое значение и пробел считаются самыми маленьким символами.

Бросается в глаза именно положение пустого значения и пробела, которые оказываются больше ряда символов (одиночный апостроф, дефис, длинные тире и др.).

Цитата:
Сообщение от Logger Посмотреть сообщение
Опасный баг. Это же может вылезти в куче мест.
Ну, это вряд ли. Типичная ситуация, когда это вылезает - это сравнение на пустоту. Мало кому в голову приходит сравнивать символьные строки на больше/меньше. Более того, должно быть не просто сравнение на пустоту, но и содержимое поля должно начинаться с символа дефиса. Достаточно редкая ситуация

Собственно, именно поэтому и не поменяли Collation на сервере. Просто не возникает проблемных ситуаций по данной причине. А там, где это надо учитывать (ну в очень специфических ситуациях) делаем специальный обход.

Цитата:
Сообщение от Logger Посмотреть сообщение
Все таки странно каким чудом дефис оказался меньше пустой строки. По логике не должно так быть. Это скорее всего бага в БД.
Не уверен, что это именно бага. Скорее просто еще один вариант сортировки

Цитата:
Сообщение от Logger Посмотреть сообщение
Интересно а что будет, если в коде Аксапты вместо
X++:
select MyTab where MyTab.MyField
поставить
X++:
select MyTab where MyTab.MyField>'-'
Так понятно, что будет. Если пустое значение больше, чем дефис, то в выборку попадут все поля с пустым значением поля

Последний раз редактировалось Владимир Максимов; 25.08.2010 в 19:58.
Старый 25.08.2010, 20:06   #15  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Спасибо за информацию.

Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Ну, это вряд ли. Типичная ситуация, когда это вылезает - это сравнение на пустоту. Мало кому в голову приходит сравнивать символьные строки на больше/меньше.
Так это ядро само такой запрос посылает. Программист может просто написать
X++:
select MyTab where MyTab.MyField
не задумываясь какой запрос уйдет. А ядро аксапты пошлет условие MyTab.MyField > ''

И кстати, я считаю что для условия на пустоту/непустоту строкого поля правильнее писать
X++:
select MyTab where MyTab.MyField
вместо
X++:
select MyTab where MyTab.MyField != ''
так как для БД проще исполнять запрос с условием ">" чем с условием "!="
Теги
collation, sql server, баг, сортировка, сравнение

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Количество строк в Query Владимир Максимов DAX: Программирование 19 11.08.2014 18:27
Баг? Сравнение строк длиной более 32767 символов vallys DAX: База знаний и проекты 6 16.07.2008 12:18
Тормозит копирование строк в буфер обмена ivas DAX: Программирование 20 21.08.2007 15:05
Сортировка строк фактуры PavelSR DAX: Программирование 11 07.09.2006 12:20
БАГ: копирование строк накладных в новый заказ Антон Солдатов DAX: Функционал 2 03.12.2004 09:02

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:03.