Как использовать ORDER BY, LOWER в SQL SERVER 2008 с данными, отличными от юникода

StackOverflow https://stackoverflow.com/questions/2543074

  •  23-09-2019
  •  | 
  •  

Вопрос

Вопрос касается армянского языка.Я использую sql server 2005, параметры сортировки SQL_Latin1_General_CP1_CI_AS, данные в основном на армянском языке, и мы не можем использовать unicode.

Я тестировал на ms sql 2008 с параметрами сортировки Windows для армянского языка ( Cyrillic_General_100_ ), я нашел здесь, ( http://msdn.microsoft.com/en-us/library/ms188046.aspx ) но это не помогло.

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

Есть ли какое-либо решение для этой проблемы, не использующее юникод и не работающее с шестнадцатеричными значениями вручную?

Обновить:

С левой стороны приведены слова со смешанным регистром, отсортированные в правильном порядке и представленные в нижнем регистре с правой стороны.Надеюсь, это поможет.Спасибо.Слова написаны в юникоде.

  1. ԱբԳդԵզ -> աբգդեզ

  2. ԱգԳսԴԼ -> ագգսդլ

  3. ԲաԴֆդԴ -> բադֆդդ

  4. ԳԳԼասա -> գգլասա

  5. ԴմմլօՏ -> դմմլօտ

  6. ԵլԲնՆն -> ելբննն

  7. ԶՎլուտ -> զվլուտ

  8. էԹփձջՐ -> էթփձջր

  9. ԸխԾդսՂ -> ըխծդսղ

  10. ԹԶէըԿր -> թզէըկր

Это было полезно?

Решение

Одним из решений было бы создать вычисляемый столбец для каждого текстового столбца, который преобразует значение в параметры сортировки на армянском языке и устанавливает его в нижний регистр следующим образом:

Alter Table TableName
    Add TextValueArmenian As ( LOWER(TextColumn COLLATE Latin1_General_CI_AS) ) PERSISTED

Как только вы сделаете это, вы можете поместить индексы в эти столбцы и запросить их.

Если это не ваш вкус чая, то другим решением было бы индексированное представление, в котором вы создаете представление с SCHEMABINDING это переводит каждый из различных столбцов в нижний регистр и в правильную сортировку, а затем помещает индексы в это представление.

Редактировать Я заметил в ваших примерах, что вы используете регистрозависимый, чувствительный к ударению.Возможно, простым решением ваших проблем с заказом было бы использовать Latin1_General_CS_AS или Cyrillic_General_100_CS_AS, если таковые имеются.

Редактировать

Фух.После довольно продолжительных исследований, я думаю, у меня есть ответ, который, к сожалению, может вам не понравиться.Во-первых, да, я могу скопировать предоставленный вами текст в код или что-то вроде Notepad ++, потому что StackOverflow кодируется с использованием UTF-8, а армянский язык будет вписываться в UTF-8.Во-вторых, это намекает на то, чего вы пытаетесь достичь:хранение UTF-8 в SQL Server.К сожалению, SQL Server 2008 (или любая предыдущая версия) изначально не поддерживает UTF-8.Для того чтобы хранить данные в формате UTF-8, у вас есть несколько вариантов:

  1. Сохраните его в двоичном формате и преобразуйте в UTF-8 на клиенте (что в значительной степени исключает любую сортировку, выполняемую на сервере)
  2. Сохраните его в Юникоде и преобразуйте в UTF-8 на клиенте.Следует отметить, что драйвер SQL Server уже преобразует большинство строк в Юникод, и ваш пример отлично работает в Юникоде.Очевидным недостатком является то, что он занимает в два раза больше места.
  3. Создайте пользовательский тип CLR в SQL Server для хранения значений UTF-8.Корпорация Майкрософт предоставляет образец, поставляемый с SQL Server, именно для этого.Вы можете загрузить образцы с CodePlex отсюда.Вы также можете найти более подробную информацию о образце в этой статье в Книги онлайн.Недостатком является то, что у вас должна быть включена среда CLR в SQL Server, и я не уверен, насколько хорошо она будет работать.

Теперь, тем не менее, я смог без проблем предоставить вам образец работы с использованием Unicode в SQL Server.

If object_id('tempdb..#Test') Is Not Null
    Drop Table #Test
GO
Create Table #Test
(
    EntrySort int identity(1,1) not null
    , ProperSort int 
    , MixedCase nvarchar(50)
    , Lowercase nvarchar(50)
)
GO
Insert #Test(ProperSort, MixedCase, Lowercase)
Select 1, N'ԱբԳդԵզ',N'աբգդեզ'
Union All Select 6, N'ԵլԲնՆն',N'ելբննն'
Union All Select 2, N'ԱգԳսԴԼ',N'ագգսդլ'
Union All Select 3, N'ԲաԴֆդԴ',N'բադֆդդ'
Union All Select 4, N'ԳԳԼասա',N'գգլասա'
Union All Select 5, N'ԴմմլօՏ',N'դմմլօտ'
Union All Select 9, N'ԸխԾդսՂ',N'ըխծդսղ'
Union All Select 7, N'ԶՎլուտ',N'զվլուտ'
Union All Select 10, N'ԹԶէըԿր',N'թզէըկր'
Union All Select 8,N'էԹփձջՐ',N'էթփձջր'

Select * From #Test Order by ProperSort
Select * From #Test Order by Lowercase
Select * From #Test Order by Lower(MixedCase)

Все три этих запроса возвращают один и тот же результат.

Другие советы

Вы получили подобную ошибку?

Msg 448, Level 16, State 1, Line 1
Invalid collation 'Cyrillic_General_100_'.

Попробуй:

ORDER BY Name COLLATE Cyrillic_General_100_CI_AS

Или выберите тот, который вам больше нравится из этого списка:

select * from fn_helpcollations()
where name like 'Cyrillic_General_100_%'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top