是否有任何函数可以在T-SQL中编码HTML字符串?我有一个遗留数据库,其中包含诸如"<",">"之类的躲避字符等.我可以编写一个函数来替换字符但是有更好的方法吗?
我有一个ASP.Net应用程序,当它返回一个字符串时,它包含导致错误的字符.ASP.Net应用程序正在从数据库表中读取数据.它不会写入表本身.
我们有一个遗留系统,它使用触发器和dbmail在输入表时发送HTML编码的电子邮件,因此我们需要在电子邮件生成中进行编码.我注意到Leo的版本有一个小的bug来编码&in <
并>
使用这个版本:
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 < will become < SELECT @Encoded = Replace( Replace( Replace(@UnEncoded,'&','&'), '<', '<'), '>', '>') RETURN @Encoded END GO
这有点晚了,但无论如何,这里有正确的方法:
HTML-Encode(HTML编码= XML编码):
DECLARE @s NVARCHAR(100) SET @s = 'unsafe & safe Utf8CharsDon''tGetEncoded ÄöÜ - "Conex"' SELECT (SELECT @s FOR XML PATH(''))
查询中的HTML编码:
SELECT FIELD_NAME ,(SELECT FIELD_NAME AS [text()] FOR XML PATH('')) AS FIELD_NAME_HtmlENcoded FROM TABLE_NAME
HTML解码:
SELECT CAST('' + '<root>Test&123' + ' ' AS XML).value(N'(root)[1]', N'varchar(max)');
如果要正确执行,可以使用CLR存储过程.
但是,它有点复杂,因为你不能在CLR-stored-procedures中使用System.Web-Assembly(所以你不能做System.Web.HttpUtility.HtmlDecode(htmlEncodedStr);).所以你必须编写自己的HttpUtility类,我不推荐,特别是对于解码.
幸运的是,您可以从单一源代码(.NET for Linux)中删除System.Web.HttpUtility.然后你可以在不引用system.web的情况下使用HttpUtility.
然后你写这个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äÖü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
您不应该在SQL中修复该字符串.更好的方法是在ASP.net中使用一个名为HtmlEncode的函数,这将烹饪导致您看到的问题的特殊字符,请参阅下面的示例.我希望这有帮助.
string htmlEncodedStr = System.Web.HttpUtility.HtmlEncode(yourRawStringVariableHere); string decodedRawStr = System.Web.HttpUtility.HtmlDecode(htmlEncodedStr);
编辑:因为您是从数据表绑定数据.使用内联表达式在GridView的标记或您使用的任何控件中调用HTMLEncode,这仍将满足您的数据绑定要求.见下面的例子.或者,您可以循环数据表对象中的每个记录,并在数据绑定之前使用html编码的字符串更新每个单元格.
<%# System.Web.HttpUtility.HtmlEncode(Eval("YourColumnNameHere")) %>
我不认为数据库中的数据应该知道或关心用户界面.显示问题应由表示层处理.我不希望看到任何混入数据库的HTML.