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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 05.03.2009, 19:05   #1  
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   #2  
Владимир Максимов 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   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 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   #4  
Владимир Максимов 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   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 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, время: 14:42.