Вот простая функция кодирования 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 не лучший язык для работы со строками.