Преобразование значения в формат, удобный для URL - Unicode декомпозиция ähhh - PullRequest
3 голосов
/ 05 августа 2009

Мне нужно преобразовать значение «Преобразовать значение в формат, дружественный к URL - разложение Юникод ähhh» в «Преобразовать значение в дружественный URL-адрес-формат-юникод-разложение-ааа». Возможно ли это в SQL-сервере? Все Unicode - символы должны быть обработаны.

Я использую SQL-Server 2005, 2008 в качестве опции.

EDIT

У Богдана было решение, которое работало на меня.

Запрос зависит от символов, которые вам нужно обработать, но в большинстве случаев все должно быть в порядке. Вам действительно нужно передать сопоставление, в котором не содержит символы, которые нужно изменить. Кириллица хороша для этого. Это что-то вроде хаки ...

объявить @input nvarchar (4000) set @input = 'áâãäåæçèéêëìíîïðñòóôõöùúûüýÿāăąćĉċčĕėęěĝğġģĥħĩīĭįĵķļľńňŋōŏőŕřśŝşšťũūŭůűŵŷźžǻǽǿ'

SELECT CAST (@input as char (4000)) COLLATE Cyrillic_General_CI_A S

Ответы [ 2 ]

4 голосов
/ 06 августа 2009

Вот простая функция кодирования URL (она использует varchar в качестве параметра), которую я давно нашел на каком-то форуме

create function urlencode(@str as varchar(4000))
returns varchar(4000)
as
begin
declare @hex char(16)
declare @c char(1)
set @hex='0123456789ABCDEF'
declare @ostr varchar(4000)
set @ostr=''
declare @l int
set @l = 1
while @l <= len(@str)
begin
 set @c = substring(@str,@l,1)
 if @c between '0' and '9'
 or @c between 'A' and 'Z'
 or @c between 'a' and 'z'
  set @ostr = @ostr + @c
  else
  set @ostr = @ostr + '%' +
    substring(@hex,(ascii(@c)/16)+1,1)
   +substring(@hex,(ascii(@c)&15)+1,1)
 set @l=@l+1
end
return @ostr
end
go 

Как вы будете обрабатывать юникод? Что ж, это довольно просто, если вы не заботитесь об индуистских или арабских символах, но заботитесь о языках Центральной Европы. Вам просто нужно использовать функцию CAST (@nvarchar как varchar) .

Давайте посмотрим, как это работает с некоторыми символами Центральной Европы. Запустите следующий пример в

declare @t1 nvarchar(256)
select @t1 = N'áâãäåæçèéêëìíîïðñòóôõöùúûüýÿāăąćĉċčĕėęěĝğġģĥħĩīĭįĵķļľńňŋōŏőŕřśŝşšťũūŭůűŵŷźžǻǽǿ'
select @t1
declare @t2 varchar(512)
select @t2 = cast(@t1 as varchar(512))
select @t2

И посмотрим, что мы получим

áâãäåæçèéêëìíîïðñòóôõöùúûüýÿāăąćĉċčĕėęěĝğġģĥħĩīĭįĵķļľńňŋōŏőŕřśŝşšťũūŭůűŵŷźžǻǽǿ
aaaaa?ceeeeiiii?nooooouuuuyyaaacccceeeegggghhiiiijkllnn?ooorrsssstuuuuuwyzz???

Итак, большинство символов конвертируются отлично, тогда как несколько символов станут знаками вопроса. Если вы заботитесь о таких символах (таких как æ, ð, ŋ), вам нужно написать дополнительную функцию, которая заменит их перед преобразованием в то, что вы найдете наиболее подходящим для них (иногда 2 символа вместо одного, например, æ = > ае).

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

1) Создать временную таблицу (или переменную типа таблицы) с 3 столбцами - позиция int identity (0,1), первичный ключ кластеризован, исходный nchar (1) не нулевой, преобразованный varchar (2) нулевой 2) Используя цикл и функцию SUBSTRING (), разбейте строку на символы и вставьте каждый символ в столбец original этой временной таблицы. 3) Использование одного запроса со многими, КОГДА ТОГДА операторы преобразуют все символы

update @temp_table
set converted = CASE original 
     WHEN N'æ' THEN 'ae' 
     WHEN N'ŋ' THEN 'n'
     ... and so on ...
     ELSE CAST(original AS VARCHAR(2))

4) Используя цикл, объедините результаты, которые вы получили в , преобразованном столбце в одну переменную varchar ().

Когда вы преобразовали nvarchar () в varchar (), вызовите функцию urlencode (), которую я перечислил выше.

Я понимаю, что в этом случае потребуется много КОГДА / ТО, но это зависит от того, какие языки у вас есть в настоящее время. Как видите, для большинства европейских символов CAST varchar дает идеальный результат.

Если вы пойдете с реализацией функции CLR (на C #), вам также придется написать много операторов switch / case. Таким образом, сравнивая оба подхода, оба потребуют одинаковых усилий по разработке, но решение CLR потребует дополнительных административных действий. Для небольших строк решение CLR будет работать медленно (поскольку SQL-серверу требуется некоторое время для взаимодействия со средой CLR, чтобы выполнить вызов, а затем получить результаты), в то время как для больших строк с большим количеством замен C # возможно (никогда не проверял это!) может быть быстрее, потому что SQL не лучший язык для работы со строками.

0 голосов
/ 05 августа 2009

Да, это возможно. Ответ - «Пользовательская функция со скалярным значением» (UDF).

Здесь я вижу два варианта:

  1. Создание UDF в T-SQL - требует довольно больших усилий, большой работы с кодами символов [я так понимаю] и будет «не таким быстрым».
  2. Создание пользовательского интерфейса CLR - намного быстрее и проще, если вы знакомы с .NET.

Второй вариант потребует от вас разрешения интеграции CLR в SQL Server, помимо создания сборки с функцией и ее развертывания на серверах:

exec sp_configure 'clr enabled', 1
RECONFIGURE

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...