2013-02-26 36 views
2

我使用這個函數用於URL編碼的字符串解碼:地址解碼T-SQL函數沒有翻譯出來的ASCII字符範圍

ALTER FUNCTION [dbo].[UrlDecode](@url varchar(3072)) 
RETURNS varchar(3072) 
AS 
BEGIN 
    DECLARE @Position INT, 
     @Base CHAR(16), 
     @High TINYINT, 
     @Low TINYINT, 
     @Pattern CHAR(21) 

    SELECT @Base = 'abcdef', 
     @Pattern = '%[%][0-9a-f][0-9a-f]%', 
     @URL = REPLACE(@URL, '+', ' '), 
     @Position = PATINDEX(@Pattern, @URL) 

    WHILE @Position > 0 
     SELECT @High = CHARINDEX(SUBSTRING(@URL, @Position + 1, 1), @Base COLLATE Latin1_General_CI_AS), 
      @Low = CHARINDEX(SUBSTRING(@URL, @Position + 2, 1), @Base COLLATE Latin1_General_CI_AS), 
      @URL = STUFF(@URL, @Position, 3, CHAR(16 * @High + @Low - 17)), 
      @Position = PATINDEX(@Pattern, @URL) 

    RETURN @URL + 
END 

這工作得很好,直到它達到了專用的ASCII字符範圍。例如:Wil+SG+1將返回Wil SG 1這是OK。雖然Gen%C3%A8ve+11返回Genève 11這不是我所期望的(Genève 11是在這種情況下的預期結果)。

另一個例子:

select 'Gen%C3%A8ve+2+D%C3%A9p%C3%B4t', dbo.UrlDecode('Gen%C3%A8ve+2+D%C3%A9p%C3%B4t') 

回報:

Gen%C3%A8ve+2+D%C3%A9p%C3%B4t Genève 2 Dépôt 

我一直在使用NCHAR,而不是CHAR嘗試,但結果是一樣的。你知道我能做些什麼來支持這些擴展的ASCII字符嗎?

+1

我覺得這個鏈接可以幫助 - > http://stackoverflow.com/questions/3585138/how-can-i-convert-a字符串到字符串編碼在utf-8中,反之亦然 – 2013-02-26 16:05:30

+0

您的例程不會編譯,因爲'RETURN @URL +'不是有效的SQL語句。這條線應該是什麼? – RBarryYoung 2013-02-26 20:06:38

+1

等一下,***爲什麼你會期望'Gen%C3%A8ve + 11'能夠歸還'Genève11'?不是UC + 00C3 =「Ã」?這會讓'Genève11'成爲正確的答案。 'Genève11'甚至沒有正確的長度?!? – RBarryYoung 2013-02-26 20:32:31

回答

2

,我發現這個功能實現正是我想要的:

ALTER FUNCTION [dbo].[UrlDecodeUTF8](@URL varchar(3072)) 
RETURNS varchar(3072) 
AS 
BEGIN 
    DECLARE @Position INT, 
     @Base CHAR(16), 
     @Code INT, 
     @Pattern CHAR(21) 

    SELECT @URL = REPLACE(@URL, '%c3', '') 

    SELECT @Base = 'abcdef', 
     @Pattern = '%[%][0-9a-f][0-9a-f]%', 
     @Position = PATINDEX(@Pattern, @URL) 

    WHILE @Position > 0 
     SELECT @Code = Cast(CONVERT(varbinary(4), '0x' + SUBSTRING(@URL, @Position + 1, 2), 1) As int), 
      @URL = STUFF(@URL, @Position, 3, NCHAR(@Code + 64)), 
      @Position = PATINDEX(@Pattern, @URL) 

    RETURN REPLACE(@URL, '+', ' ') 

END 
-1

我懷疑你需要使用排序規則,用一些ascii等效替換UTF代碼。以下是我的代碼庫中的示例:

REPLACE(CHAR(228) COLLATE Latin1_General_BIN, CHAR(196), 'Y') 
+0

感謝您的回答,但我意識到與mehdi的評論,它是utf8編碼,所以我必須解碼utf8 – 2013-02-27 07:40:30

3

URL以UTF-8編碼。你的函數所做的僅僅是將URL的UTF-8表示的十六進制代碼替換爲與十六進制代碼匹配的字符。

您真正需要的是將URL編碼的UTF-8替換爲MSSQL UCS-2的函數,如發佈在answer on Social.MSDN中。

+0

你是絕對正確的感謝您的答案,但我意識到,與mehdi的評論。不管怎麼說,還是要謝謝你。 – 2013-02-27 07:42:28