Aquí podría ser tu PUBLICIDAD


Codificación HTML en T-SQL?

votos
13

¿Hay alguna función para codificar cadenas HTML en T-SQL? Tengo una base de datos heredada que contiene caracteres dudosos como '<', '>', etc. Puedo escribir una función para reemplazar los caracteres, pero ¿hay alguna otra manera mejor?

Tengo una aplicación ASP.Net y cuando devuelve una cadena, contiene caracteres que causan un error. La aplicación ASP.Net está leyendo los datos de una tabla de base de datos. No escribe en la tabla en sí.

Publicado el 12/03/2009 a las 17:18
fuente por usuario Leo Moore
En otros idiomas...        العربية       

10 respuestas

votos
21

Tenemos un sistema heredado que usa un disparador y un dbmail para enviar un correo electrónico con codificación HTML cuando se ingresa una tabla, por lo que necesitamos codificación dentro de la generación del correo electrónico. Noté que la versión de Leo tiene un pequeño error que codifica el y en &lt;y &gt;yo uso esta versión:

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
Respondida el 25/09/2009 a las 11:33
fuente por usuario Beniaminus


Aquí podría ser tu PUBLICIDAD


votos
19

Es un poco tarde, pero de todos modos, aquí las formas adecuadas:

La codificación HTML (HTML codificación XML = codificación):

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

La codificación HTML en una consulta:

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

HTML-Decode:

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

Si desea hacerlo correctamente, se puede utilizar un procedimiento CLR-almacenado.
Sin embargo, se hace un poco complicado, porque no se puede utilizar el System.Web-Asamblea de CLR-almacenado-tratamientos (por lo que no puede hacer System.Web.HttpUtility.HtmlDecode (htmlEncodedStr);). Así que hay que escribir su propia clase HttpUtility, que no lo recomendaría, especialmente para la decodificación.

Afortunadamente, usted puede rasgar System.Web.HttpUtility fuera del código fuente mono (.NET para Linux). A continuación, puede utilizar HttpUtility sin hacer referencia system.web.

A continuación, se escribe este CLR-almacenado-Procedimiento:

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

Y registrarlo:

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;
*/

Después, se puede usar como funciones normales:

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

Cualquier persona que acaba de copiar-pastas, tenga en cuenta que por razones de eficiencia, se utilizaría

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;
}

si lo utiliza esta función en la producción.

Vea aquí las clases mono editados:
http://pastebin.com/pXi57iZ3
http://pastebin.com/2bfGKBte

Es necesario definir NET_2_0 en las opciones de generación opciones de construcción

Respondida el 09/01/2013 a las 01:00
fuente por usuario Stefan Steiger

votos
14

No deberías corregir la cadena en SQL. Una mejor manera es usar una función en ASP.net llamada HtmlEncode, esto cocinará los caracteres especiales que causan los problemas que está viendo, vea el ejemplo a continuación. Espero que esto ayude.

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

Editar: como estás vinculando datos esto desde una tabla de datos. Use una expresión en línea para llamar a HTMLEncode en el marcado de GridView o lo que controle su uso y esto aún satisfará su requisito de enlace de datos. Vea el ejemplo a continuación. Alternativamente, puede recorrer cada registro en el objeto de la tabla de datos y actualizar cada celda con la cadena codificada html antes del enlace de datos.

<%# System.Web.HttpUtility.HtmlEncode(Eval("YourColumnNameHere")) %>
Respondida el 12/03/2009 a las 05:22
fuente por usuario James

votos
8

No creo que los datos de una base de datos deban saber o preocuparse por la interfaz de usuario. Los problemas de visualización deben ser manejados por la capa de presentación. No me gustaría ver ningún HTML mezclado en la base de datos.

Respondida el 12/03/2009 a las 06:20
fuente por usuario duffymo

votos
2

Usted puede simplemente utilizar 'PATH XML en la consulta'. Por ejemplo;

DECLARE @encodedString VARCHAR (MAX)

@encodedString SET = 'darle a su cadena HTML que quiere codificar'

@encodedString SELECT
SELECT (SELECCIONAR @encodedString para la ruta XML ( ''))

Ahora como su deseo que pueda usted esto en su propia función de SQL. Esperamos que esto ayude.

Respondida el 16/12/2016 a las 01:11
fuente por usuario sumith madhushan

votos
2

Si está mostrando una cadena en la web, puede codificarla con Server.HTMLEncode ().

Si está almacenando una cadena en la base de datos, asegúrese de que el campo de la base de datos sea "nchar", en lugar de "char". Eso le permitirá almacenar cadenas de caracteres unicode.

Si no puede controlar la base de datos, puede "aplanar" la cadena a ASCII con Encoding.ASCII.GetString.

Respondida el 12/03/2009 a las 05:33
fuente por usuario Andomar

votos
0

He estado tratando de hacer esto hoy en T-SQL, sobre todo para la diversión en este punto ya que mis requisitos cambian, pero pensé que una salida. Se puede utilizar una tabla de caracteres Unicode, construido a partir de la función NCHAR () o simplemente importarlo, la iteración del 0 al 65535. (o menos si sólo tiene el primer 512 o algo así). Luego reconstruir la cadena. Probablemente hay mejores maneras de reconstruir la cadena, pero esto funciona en caso de apuro.

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

`

CREAR #UnicodeCharacters TABLA (DecimalValue INT, UnicodeCharacter NCHAR);

--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 IGNORE  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
;

`Sé que normalmente se usaría [0-9A-Za-z], pero por alguna razón, se considera caracteres acentuados dentro del alcance de esta expresión cuando hice eso. Así que he usado de forma explícita todos los personajes que no me quiero convertir a Unicode en la expresión.

Última nota, que tenía que utilizar una intercalación diferente para hacer partidos de caracteres Unicode, debido a que la colación por defecto AMÉRICA (CI o de otro tipo) parecía coincidir incorrectamente en caracteres acentuados, al igual que la expresión regular en el estilo.

Respondida el 04/07/2018 a las 12:55
fuente por usuario Jeremy Giaco

votos
0

No he probado esta solución mí mismo, pero lo que me gustaría probar es utilizar la integración de SQL CLR servidor / .NET y en realidad llama a la función HTMLEncode C # desde el T-SQL. Esto puede ser ineficiente pero sospecho que le daría el resultado más preciso.

Mi punto de partida para la elaboración de la forma de hacer esto sería http://msdn.microsoft.com/en-us/library/ms254498%28VS.80%29.aspx

Respondida el 29/07/2011 a las 02:09
fuente por usuario Mark

votos
0

asignarlo a la propiedad de texto de la etiqueta, será automático codificada por .NET

Respondida el 08/11/2010 a las 04:40
fuente por usuario Saurabh

votos
0

OK, aquí está lo que hice. Creé una función simple para manejarlo. Está lejos de ser completo, pero al menos maneja los <>&personajes estándar . Añadiré a medida que avance.

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

Puedo usar:

Select Ref,dbo.HtmlEncode(RecID) from Customers

Esto me da una ID de registro segura de HTML. Probablemente haya una función integrada pero no puedo encontrarla.

Respondida el 15/03/2009 a las 08:40
fuente por usuario Leo Moore


Aquí podría ser tu PUBLICIDAD