代码之家  ›  专栏  ›  技术社区  ›  Leo Moore

T-SQL中的HTML编码?

  •  16
  • Leo Moore  · 技术社区  · 16 年前

    在T-SQL中是否有编码HTML字符串的函数?我有一个遗留数据库,其中包含诸如“<”、”等狡猾的字符>'我可以写一个函数来替换字符,但是有更好的方法吗?

    我有一个ASP.Net应用程序,当它返回一个字符串时,它包含导致错误的字符。ASP.Net应用程序正在从数据库表读取数据。它不会写入表本身。

    10 回复  |  直到 16 年前
        1
  •  27
  •   Beniaminus    15 年前

    我们有一个遗留系统,它使用触发器和dbmail在输入表时发送HTML编码的电子邮件,因此我们需要在电子邮件生成中进行编码。我注意到Leo的版本有一个轻微的错误,对&在里面 &lt; &gt; 我使用这个版本:

    CREATE FUNCTION HtmlEncode
    (
        @UnEncoded as varchar(500)
    )
    RETURNS varchar(500)
    AS
    BEGIN
      DECLARE @Encoded as varchar(500)
    
      --order is important here. Replace the amp first, then the lt and gt. 
      --otherwise the &lt will become &amp;lt; 
      SELECT @Encoded = 
      Replace(
        Replace(
          Replace(@UnEncoded,'&','&amp;'),
        '<', '&lt;'),
      '>', '&gt;')
    
      RETURN @Encoded
    END
    GO
    
        2
  •  27
  •   Stefan Steiger Marco van de Voort    12 年前

    有点晚了,但无论如何,这里有正确的方法:

    HTML编码(HTML编码=XML编码):

    DECLARE @s NVARCHAR(100)
    SET @s = '<html>unsafe & safe Utf8CharsDon''tGetEncoded ÄöÜ - "Conex"<html>'
    SELECT (SELECT @s FOR XML PATH(''))
    

    SELECT 
        FIELD_NAME  
        ,(SELECT FIELD_NAME AS [text()] FOR XML PATH('')) AS FIELD_NAME_HtmlENcoded 
    FROM TABLE_NAME
    

    HTML解码:

    SELECT CAST('<root>' + '&lt;root&gt;Test&amp;123' + '</root>' AS XML).value(N'(root)[1]', N'varchar(max)');
    

    如果要正确执行,可以使用CLR存储过程。

    幸运的是,您可以从mono源代码(.NET for Linux)中删除System.Web.HttpUtility。然后,您可以使用HttpUtility而无需引用system.web。

    然后编写以下CLR存储过程:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    using Microsoft.SqlServer.Server;
    using System.Data.SqlTypes;
    //using Microsoft.SqlServer.Types;
    
    
    namespace ClrFunctionsLibrary
    {
    
    
        public class Test
        {
    
    
            [Microsoft.SqlServer.Server.SqlFunction]
            public static SqlString HtmlEncode(SqlString sqlstrTextThatNeedsEncoding)
            {
                string strHtmlEncoded = System.Web.HttpUtility.HtmlEncode(sqlstrTextThatNeedsEncoding.Value);
                SqlString sqlstrReturnValue = new SqlString(strHtmlEncoded);
    
                return sqlstrReturnValue;
            }
    
    
            [Microsoft.SqlServer.Server.SqlFunction]
            public static SqlString HtmlDecode(SqlString sqlstrHtmlEncodedText)
            {
                string strHtmlDecoded = System.Web.HttpUtility.HtmlDecode(sqlstrHtmlEncodedText.Value);
                SqlString sqlstrReturnValue = new SqlString(strHtmlDecoded);
    
                return sqlstrReturnValue;
            }
    
    
            // ClrFunctionsLibrary.Test.GetPassword
            //[Microsoft.SqlServer.Server.SqlFunction]
            //public static SqlString GetPassword(SqlString sqlstrEncryptedPassword)
            //{
            //    string strDecryptedPassword = libPortalSecurity.AperturePortal.DecryptPassword(sqlstrEncryptedPassword.Value);
            //    SqlString sqlstrReturnValue = new SqlString(sqlstrEncryptedPassword.Value + "hello");
    
            //    return sqlstrReturnValue;
            //}
    
            public const double SALES_TAX = .086;
    
            // http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.80).aspx
            [SqlFunction()]
            public static SqlDouble addTax(SqlDouble originalAmount)
            {
                SqlDouble taxAmount = originalAmount * SALES_TAX;
    
                return originalAmount + taxAmount;
            }
    
    
        } // End Class Test
    
    
    } // End Namespace ClrFunctionsLibrary
    

    并登记:

    GO
    
    /*
    --http://stackoverflow.com/questions/72281/error-running-clr-stored-proc
    -- For unsafe permission
    EXEC sp_changedbowner 'sa'
    ALTER DATABASE YOUR_DB_NAME SET TRUSTWORTHY ON 
    
    GO
    */
    
    
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[HtmlEncode]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
    DROP FUNCTION [dbo].[HtmlEncode]
    GO
    
    
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[HtmlDecode]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
    DROP FUNCTION [dbo].[HtmlDecode]
    GO
    
    
    
    
    IF  EXISTS (SELECT * FROM sys.assemblies asms WHERE asms.name = N'ClrFunctionsLibrary' and is_user_defined = 1)
    DROP ASSEMBLY [ClrFunctionsLibrary]
    
    GO
    
    
    --http://msdn.microsoft.com/en-us/library/ms345101.aspx
    
    
    
    CREATE ASSEMBLY [ClrFunctionsLibrary]
    AUTHORIZATION [dbo]
    FROM 'D:\username\documents\visual studio 2010\Projects\ClrFunctionsLibrary\ClrFunctionsLibrary\bin\Debug\ClrFunctionsLibrary.dll' 
    WITH PERMISSION_SET = UNSAFE  --EXTERNAL_ACCESS  --SAFE
    ;
    
    GO
    
    
    
    
    CREATE FUNCTION [dbo].[HtmlDecode](@value [nvarchar](max))
    RETURNS [nvarchar](max) WITH EXECUTE AS CALLER
    AS 
    -- [AssemblyName].[Namespace.Class].[FunctionName]
    EXTERNAL NAME [ClrFunctionsLibrary].[ClrFunctionsLibrary.Test].[HtmlDecode]
    GO
    
    
    
    
    
    CREATE FUNCTION [dbo].[HtmlEncode](@value [nvarchar](max))
    RETURNS [nvarchar](max) WITH EXECUTE AS CALLER
    AS 
    -- [AssemblyName].[Namespace.Class].[FunctionName]
    EXTERNAL NAME [ClrFunctionsLibrary].[ClrFunctionsLibrary.Test].[HtmlEncode]
    GO
    
    
    
    /*
    EXEC sp_CONFIGURE 'show advanced options' , '1';
     GO
     RECONFIGURE;
     GO
     EXEC sp_CONFIGURE 'clr enabled' , '1'
     GO
     RECONFIGURE;
     GO
    
    EXEC sp_CONFIGURE 'show advanced options' , '0';
     GO
     RECONFIGURE;
    */
    

    之后,您可以像正常功能一样使用它:

    SELECT
         dbo.HtmlEncode('helloäÖühello123') AS Encoded
        ,dbo.HtmlDecode('hello&auml;&Ouml;&uuml;hello123') AS Decoded 
    

    public const double SALES_TAX = 1.086;
    
    // http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.80).aspx
    [SqlFunction()]
    public static SqlDouble addTax(SqlDouble originalAmount)
    {
         return originalAmount * SALES_TAX;
    }
    

    如果你想在生产中使用这个功能。


    http://pastebin.com/pXi57iZ3
    http://pastebin.com/2bfGKBte

    您需要在构建选项中定义NET_2_0 Build options

        3
  •  14
  •   James    16 年前

    string htmlEncodedStr = System.Web.HttpUtility.HtmlEncode(yourRawStringVariableHere);
    string decodedRawStr =  System.Web.HttpUtility.HtmlDecode(htmlEncodedStr);
    

    编辑: 因为您是从datatable绑定数据。使用内联表达式在GridView的标记中调用HTMLEncode,或者使用任何控件,这样仍然可以满足数据绑定要求。见下面的例子。或者,您可以循环数据表对象中的每个记录,并在数据绑定之前使用html编码的字符串更新每个单元格。

    <%# System.Web.HttpUtility.HtmlEncode(Eval("YourColumnNameHere")) %>
    
        4
  •  7
  •   duffymo    16 年前

    我认为数据库中的数据不应该知道或关心用户界面。显示问题应由表示层处理。我不想看到任何HTML混合到数据库中。

        5
  •  4
  •   sumith madhushan    8 年前

    您可以简单地使用“查询中的XML路径”。例如

    DECLARE @encodedString VARCHAR(MAX)
    
    SET @encodedString = 'give your html string you want to encode'
    
    SELECT @encodedString
    SELECT (SELECT @encodedString FOR XML PATH(''))
    
    

    现在,如您所愿,您可以在自己的sql函数中实现这一点。希望这会有所帮助。

        6
  •  2
  •   Andomar    16 年前

    如果无法控制数据库,可以使用Encoding.ASCII.GetString将字符串“展平”为ASCII。

        7
  •  0
  •   Mark    13 年前

    我自己还没有尝试过这个解决方案,但我会尝试使用sql server/.NET CLR集成,并实际从t-sql调用C#HTMLEncode函数。 这可能效率低下,但我怀疑它会给你最准确的结果。

    http://msdn.microsoft.com/en-us/library/ms254498%28VS.80%29.aspx

        8
  •  0
  •   Jeremy Giaco    6 年前

    今天我一直在用T-SQL做这件事,主要是为了好玩,因为我的需求改变了,但我找到了一个解决办法。您可以使用由NCHAR()函数生成的unicode字符表,也可以直接导入它,从0迭代到65535(如果您只需要前512个字符或其他字符,则可以使用更少的字符)。然后重建字符串。可能有更好的方法来重建字符串,但这在紧要关头起作用。

    ---store unicode chars into a table so you can replace those characters withthe decimal value
    
    `
    

    创建表#Unicode字符( 单字符 ) ;

    --loop from 0 to highest unicode value you want and dump to the table you created
    DECLARE @x INT = 0;
    WHILE @x <= 65535
        BEGIN
            BEGIN
                INSERT INTO #UnicodeCharacters(DecimalValue, UnicodeCharacter)
                SELECT  @x,NCHAR(@x)
            END
            ;
    
            SET @x = @x + 1
            ;
        END
    ;
    
    --index for fast retrieval
    CREATE CLUSTERED INDEX CX_UnicodeCharacter_DecimalValue ON #UnicodeCharacters(UnicodeCharacter, DecimalValue);
    
    --this is the string that you want to html-encode...
    DECLARE @String NVARCHAR(100) = N'人This is a test - Ñ';
    
    --other vars
    DECLARE @NewString NVARCHAR(100) = '';
    DECLARE @Word TABLE(Character NCHAR(1));
    DECLARE @Pos INT = 1;
    
    --run through the string and check each character to see if it is outside the regex expression
    WHILE @Pos <= LEN(@String)
    BEGIN
        DECLARE @Letter NCHAR(1) = SUBSTRING(@String,@Pos,1);
        PRINT @Letter;
        --rebuild the string replacing each unicode character outside the regex with &#[unicode value];
        SELECT  @NewString = @NewString + 
                    CASE 
                        WHEN @Letter LIKE N'%[0-9abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!@#$%^&*()_+-= ]%' THEN @Letter
                        ELSE '&#' + CAST(uc.DecimalValue AS VARCHAR(10)) + ';'
                    END
        FROM    #UnicodeCharacters uc
        WHERE   @Letter = uc.UnicodeCharacter COLLATE JAPANESE_UNICODE_BIN
    
        SET @Pos += 1
    END
    
    --end result
    SELECT @NewString
    ;
    

    ` 我知道您通常会使用[0-9A-Za-z],但出于某种原因,在我这样做时,它考虑了该表达式范围内的重音字符。所以我在表达式中显式地使用了我不想转换为Unicode的每个字符。

        9
  •  -1
  •   Saurabh    14 年前

    将其分配给标签的文本属性,它将由.NET自动编码

        10
  •  -1
  •   p.campbell    11 年前

    好的,这就是我所做的。我创建了一个简单的函数来处理它。它远未完成,但至少符合标准 <>& 人物。我会在继续的时候再加上。

    CREATE FUNCTION HtmlEncode
    (
        @UnEncoded as varchar(500)
    )
    RETURNS varchar(500)
    AS
    BEGIN
        DECLARE @Encoded as varchar(500)   
        SELECT @Encoded = Replace(@UnEncoded,'<','&lt;')
        SELECT @Encoded = Replace(@Encoded,'>','&gt;')
        SELECT @Encoded = Replace(@Encoded,'&','&amp;')   
        RETURN @Encoded    
    END
    

    然后我可以使用:

    Select Ref,dbo.HtmlEncode(RecID) from Customers
    

    这给了我一个HTML安全记录ID。可能有一个内置函数,但我找不到它。