我正在使用此函数来解码url编码的字符串:
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 = '0123456789abcdef',
@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
,这是正常的。虽然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字符吗?
答案 0 :(得分:3)
网址以UTF-8编码。您的函数所做的只是将URL的UTF-8表示的十六进制代码替换为与十六进制代码匹配的字符。
您真正需要的是将URL编码的UTF-8替换为MSSQL UCS-2的功能,如answer on Social.MSDN中所述。
答案 1 :(得分: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 = '0123456789abcdef',
@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
答案 2 :(得分:-1)
我怀疑你需要使用整理,用一些ascii等效替换UTF代码。这是我在代码库中的一个例子:
REPLACE(CHAR(228) COLLATE Latin1_General_BIN, CHAR(196), 'Y')