lundi 23 novembre 2009

décodage des entités html en SqlServer

Pour différentes raisons il arrive qu'un algorithme d'encodage soit utilisé pour encoder des données avant de les stocker dans une DB.
Bien malheureusement, l'usage des datasets n'est pas toujours un standard. 
L'encodage devient alors un moyen commode d'éviter la corruption d'une requête sql lorsqu'une valeur de type texte contient des guillemets (quotes) ou autres caractères susceptibles de corrompre la requête..
Parmi ces types d'encodage, il existe l'encodage sous forme d'entité html (voir Wikipédia ou Zytrax pour plus d'info).
Cet encodage se base sur in formalisme permettant l'encodage de caractère à base de nom symbolique ou de valeur numérique.  C'est bien evidemment sur le codage numérique que cette fonction s'attarde.


Décodage des entités html (numérique seulement)
A titre d'exemple, voici une fonction rudimentaire décodant les entités html numériques contenu dans les champs textes.
A noter que cette fonction ne traite que les entités numériques en 3 positions/chiffres uniquement.
-- =============================================
-- Author: Domeu
-- Create date: 23 nov 2009
-- Description: Decode string containing numerical html entities
-- Changes: 
--   24 nov 2009, fix side effect when HtmlString ends with HtmlEntity
-- Example:
--   Print dbo.fnDecodeHtmlString( 'Test 10627 get completed' )
-- =============================================
CREATE FUNCTION fnDecodeHtmlString 
(
 @HtmlString varchar(Max)
)
RETURNS varchar(max)
AS
BEGIN
 -- Declare the return variable here
 DECLARE @Result varchar(max)
 DECLARE @RightPart varchar(max)
    SELECT @Result = @HtmlString

    DECLARE @iPos bigint
    DECLARE @EntityNumber varchar( 10 )
    -- Start finding &#xx; patterns
    SELECT @iPos = CHARINDEX( '&#', @Result)
    while @iPos>0
    begin
      -- Check if we have the ";" 4 digits further in the string
      -- The correct Html entity format is ""
      if SubString( @Result, @iPos+2+3, 1 )=';'
      BEGIN
      -- Correct Html Entity Detected
    -- extract entity number
    SELECT @EntityNumber = SubString( @Result, @iPos+2, CHARINDEX( ';', @Result, @iPos )- (@iPos+2) )
         -- ATTN: RightPart may be when &#xx; is the last item of the string !!!
    SELECT @RightPart = RIGHT( @Result, LEN(@Result) - CHARINDEX( ';', @Result, @iPos ) )
    SELECT @Result = LEFT( @Result, @iPos-1 ) -- String before the #;

    IF CONVERT( int, @EntityNumber )>255
    SELECT @Result = @Result + '?' -- cannot convert value > ASCII code 255
    ELSE
    SELECT @Result = @Result + CHAR( CONVERT( INT, @EntityNumber ) )
          -- ATTN: RightPart may be when x; is the last item of the string !!!
          --       Use coalesce to avoids NULL concatenation.
    SELECT @Result = @Result + coalesce( @RightPart, '' ) 
      END
      ELSE
      BEGIN
        -- &# does not start an Html Entity 
        -- Do not modify the &# and start finding the next occurence of &#
        SELECT @iPos = @iPos + 2
      END
      -- finding next occurence
      SELECT @iPos = CHARINDEX( '&#',@Result, @iPos ) 
    end
 -- Return the result of the function
 RETURN @Result
END
GO

Déclaration de fonctions utilisateurs
Juste un petit paragraphe pour mentionner une excellente référence de Sql Team concernant la création de fonction utilisateur en Sql Serveur .
Outre le définition de fonction scalaires, cet article:
  • démontre l'usage des fonctions scalaires lors de la creation de table (calculated field).
  • Aborde les fonctions "Inline Table-Value User-Defined" et "Multi-statement Table-Valued User-defined"

Aucun commentaire: