下面是一個簡單的URL編碼功能(它使用VARCHAR作爲參數),我發現很久以前就一些論壇
create function urlencode(@str as varchar(4000))
returns varchar(4000)
as
begin
declare @hex char(16)
declare @c char(1)
set @hex='ABCDEF'
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 @[email protected]+1
end
return @ostr
end
go
你將如何處理unicode?那麼,如果你不關心印度或阿拉伯符號,而是關心中歐語言,那麼這很簡單。正是你需要的是使用CAST(@nvarchar as 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個符號而不是1個,例如æ= > ae)。
要取代你可以使用REPLACE()函數,但你應該明白,如果你多次調用它,性能將受到影響。所以如果你有很多字符替換,你可以使用下面的算法
1)創建一個包含3列的臨時表(或表類型變量) - position int identity(0,1)primary key clustered,original nchar( 1)使用循環和SUBSTRING()函數將字符串拆分爲字符並將每個字符插入原始該臨時表的列 3)使用一個查詢與許多WHEN THEN語句進行轉換所有符號
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)使用循環,連接結果,您在c反轉列變成一個varchar()變量。
將nvarchar()轉換爲varchar()時,請調用上面列出的urlencode()函數。
我知道這種情況下需要很多時間/時間,但這取決於您當前的語言。正如你所看到的,對於大多數歐洲符號CAST到varchar可以給出完美的結果。
如果您將使用CLR函數實現(在C#上),您將不得不編寫大量的switch/case語句。因此,比較兩種方法都需要開發相同的工作,但CLR解決方案需要額外的管理措施。對於小字符串CLR解決方案將工作緩慢(因爲SQL服務器需要一些時間來與CLR環境進行交互以進行呼叫,然後獲得結果),而對於有大量替換的大字符串,C#也許(從未檢查過!)可以速度更快,因爲SQL不是字符串操作的最佳語言。
「所有的Unicode - 字符應該處理」,這是相當多 – 2009-08-05 14:01:40
確實如此。我可以限制範圍,因爲我猜我不需要ƺ或ƻ,甚至不需要Ƕ。但我猜這個問題並沒有真正改變;-) – 2009-08-05 15:24:01