朋友想在SQL Server中進行UrlEncode,原本想用SQLCLR包System.Web.HttpUtility.UrlEncode,但似乎SQLCLR裡不能匯入System.Web[],後來雖然找到了Peter DeBetta用T-SQL寫的UrlEncode UDF,但處理中文有問題。

一時技癢,就改寫出以下的UDF,最大的改良是可以將Unicode文字轉成%unnnn的格式。

有需要的朋友可以參考看看(SQL 2000也可以用)。 

-- =============================================
-- Author:        Jeffrey Lee
-- Create date: 2007-08-03
-- Description:    Provide UrlEncode function in SQL Server
-- =============================================
CREATE FUNCTION UrlEncode
(
    @Param NVARCHAR(2000)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @HexStr VARCHAR(MAX)
    --Use system function to convert input string to hex string
    SET @HexStr = master.dbo.fn_varbintohexstr(CONVERT(VARBINARY(MAX), @Param))
    --Remove the starting '0x'
    SET @HexStr = RIGHT(@HexStr, LEN(@HexStr)-2)
    --Declare required variables
    DECLARE @I INT, @Len INT
    DECLARE @Output VARCHAR(MAX), @S CHAR(4), @C CHAR(1)
    DECLARE @LoByte TINYINT, @HiByte TINYINT
    --Get length
    SET @Len=LEN(@HexStr)/4
    --Start with first character
    SET @I=0
    --Prepare the output string
    SET @Output=''
    WHILE @I<@Len
        BEGIN
        SET @S=SUBSTRING(@HexStr, @I*4 + 1, 4)
        IF RIGHT(@S, 2)='00'
            BEGIN
            --Try to convert 2 hex digits to char
            SET @LoByte = ASCII(SUBSTRING(@S, 2, 1)) - 48
            IF @LoByte>10 SET @LoByte = @LoByte - 39 --0x61'a'-> 10
            SET @HiByte = ASCII(SUBSTRING(@S, 1, 1)) - 48
            IF @HiByte>10 SET @HiByte = @HiByte - 39
            SET @C=CHAR(@LoByte + @HiByte * 16)
            --If it's a reserved character, don't encode
            IF @C LIKE '[A-Za-z0-9()''*-._! ]'
                SET @Output = @Output + @C 
            ELSE
                SET @Output = @Output + '%' + LEFT(@S, 2)
            END
        ELSE
            SET @Output = @Output + '%u' + RIGHT(@S, 2) + LEFT(@S, 2)
        --Move to next hex 
        SET @I = @I + 1
        END
    
RETURN @Output
END

註: 從來Google到有人想出手動載入System.Web的方法可以克服此問題。


Comments

# by 黃祥倫

請問 %unnnn的格式下須如何解密

# by Jeffrey

to 黃祥倫,可使用System.Web.HttpUtility.UrlDecode()解譯。

Post a comment


44 + 1 =