Sql server 使用TSQL进行URL解码(用于扩展Ascii)

Sql server 使用TSQL进行URL解码(用于扩展Ascii),sql-server,tsql,user-defined-functions,url-encoding,string-decoding,Sql Server,Tsql,User Defined Functions,Url Encoding,String Decoding,我需要一些帮助来微调T-SQL函数,以便正确解码包含URL的字符串。仅对查询字符串参数值进行URL编码(而不是整个URL)。原始函数在解码单字节字符时运行良好,但它不处理多字节字符。为了解决多字节字符(如西班牙语重音字符)的解码问题;我的计划是使用PATINDEX查找值,并使用查找表替换这些值(这是因为我们处理的是属于这一类别的有限数量的特殊字符) 问题: 下面指定的模式没有返回任何匹配项,因此我在这一点上几乎被卡住了 示例: 模式“%[%][0-9a-f][0-9a-f]%”适用于单字节编码字

我需要一些帮助来微调T-SQL函数,以便正确解码包含URL的字符串。仅对查询字符串参数进行URL编码(而不是整个URL)。原始函数在解码单字节字符时运行良好,但它不处理多字节字符。为了解决多字节字符(如西班牙语重音字符)的解码问题;我的计划是使用PATINDEX查找值,并使用查找表替换这些值(这是因为我们处理的是属于这一类别的有限数量的特殊字符)

问题: 下面指定的模式没有返回任何匹配项,因此我在这一点上几乎被卡住了

示例:
模式“%[%][0-9a-f][0-9a-f]%”适用于单字节编码字符。类似地,模式“%[%][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]%”应该对双字节字符(如(%C3%A9->)起作用,但它不起作用。

这是我的密码:

 DECLARE @Position INT,
    @Base CHAR(16),
    @High TINYINT,
    @Low TINYINT,
    @Pattern VARCHAR(256),
    @URL VARCHAR(8000)

SET @Url = '%26Text1%3DFrom%20Ren%C3%A9%27s'

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

PRINT 'Position: ' + + CAST(@Position AS Varchar(256))

WHILE @Position > 0
    BEGIN
    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, 6, '123456'),
        @Position = PATINDEX(@Pattern, @URL)

    PRINT 'High: ' + CAST(@High AS Varchar(256))

    PRINT @URL
END 
@模式字符(21)正在截断


我在模式中有一个语法错误。仔细阅读文档后,我意识到我需要使用额外的百分号来转义%sign。以下是有效的解决方案(用于替换值的子查询不起作用,但模式为):


你确定你指的是双字节的4组吗?Cleary%C3%A9只是两组。模式应该匹配两组双字节字符。我的理解是:[%]与“C3”前面的文字(即“%”)匹配。[0-9a-f]匹配单个字母数字字符(即“C”)。重复的[0-9a-f]与第二个字母数字字符(即3)匹配,因此[%][0-9a-f][0-9a-f]应与“%C3”匹配,同样,第二组图案应与“%A9”匹配。我缺少什么?好的,但是%C3%A9是两组双字节还是一组?%C3%A9是一组双字节,每个双字节单独编码。换言之,%C3单独等同于Ã,%A9单独等同于©但结合起来,它们应该说:“[%][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][%][0-9a-f][0-9a-f]%”同样适用于双字节字符,例如(%C3%A9->),但它不适用。”该模式是两个双字节,%C3%A9是一个。谢谢!我把它改为256(只是为了安全起见),但没有改变行为。。。意思仍然不匹配。你一贯不注意细节。varchar不是char。
set nocount on
 DECLARE @Position INT,
    @Base CHAR(16),
    @High TINYINT,
    @Low TINYINT,
    @Pattern VARCHAR(200),
    @URL VARCHAR(8000)

SET @Url = '%26Text1%3DFrom%20Ren%C3%A9%27s'

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

select @URL
select @Pattern    
select @position
    DECLARE @Position INT,
    @Base CHAR(16),
    @High TINYINT,
    @Low TINYINT,
    @Pattern nVARCHAR(256),
    @ToReplace nVARCHAR(256),
    @ReplaceWith nVARCHAR(256),
    @URL nVARCHAR(4000)

SET @Url = '%26Text1%3DFrom%20Ren%C3%A9%27s%C3'

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

  PRINT 'Position: ' + + CAST(@Position AS Varchar(256))

WHILE @Position > 0
  BEGIN
  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),
        @ToReplace = SUBSTRING(@URL, @Position, 6),
        @ReplaceWith = (SELECT COALESCE([Text], 'Something') FROM dbo.ExtendedAsciiLookup WHERE UTF = @ToReplace),
        @URL = STUFF(@URL, @Position, 6, @ReplaceWith),
        @Position = PATINDEX(@Pattern, @URL)

        PRINT 'High: ' + CAST(@High AS Varchar(256))
        PRINT '@ToReplace: ' + CAST(COALESCE(@ToReplace,'') AS nVARCHAR(256))
        PRINT 'With: ' + CAST(COALESCE(@ReplaceWith,'') AS VARCHAR(256))

        PRINT @URL
END