IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MS SQL Server Discussion :

Fonction CONTEXT_INFO varbinary(128) Comportement bizarre [2012]


Sujet :

MS SQL Server

  1. #1
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut Fonction CONTEXT_INFO varbinary(128) Comportement bizarre
    J'ai voulu utiliser la fonction CONTEXT_INFO() pour stocker des infos au format texte : Cle1=Valeur1, Cle2=Valeur2 etc..
    alors j'ai commencé par le script très simple ci-dessous
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    	DECLARE @varbinBuffer  varbinary(128) 
    	DECLARE @Buffer VARCHAR(128) ; 
     
           -- Chemin "Aller" c.à.d  Encodage du CONTEXT_INFO 
    	SET @Buffer = 'Cle1=Valeur1'; 
    	SET @varbinBuffer = CAST(@Buffer AS varbinary(128)) ; 
    	SET CONTEXT_INFO  @varbinBuffer 
     
    	-- Chemin "Retour" c.à.d Décodage de CONTEXT_INFO ) 
    	SET @Buffer = CAST( CONTEXT_INFO() AS varchar(128) ) 
            SET @Buffer = REPLACE(@Buffer, char(0) , char(32) );  -- Non concluant !  ne permet pas de résoudre le problème ! 
    	SET @Buffer = LTRIM(RTRIM(@Buffer)); 
    	SELECT @buffer As Buffer , '<v>'+ @buffer + '</v>' As Buffer_Xml, 	 
    	           LEN(@Buffer) As Len_Buffer, 
    		   DATALENGTH(@Buffer) as Datalength_Buffer
    Résultat :
    Code SQL' : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Buffer			Buffer_Xml			Len_Buffer	Datalength_Buffer
    Cle1=Valeur1	<v>Cle1=Valeur1		128			128
    Le problème est que je m'attend à avoir dans la colonne Buffer_xml la valeur suivante :
    '<v>Cle1=Valeur1</v>'
    et comme vous pouvez le constater il manque la balise de fermeture </v>. (Ce qui génère évidement des erreurs dans d'autres traitements XML. (mais là n'est pas le problème, ce dernier, se situe ici, bien en amont).
    Ce que je ne comprend pas c'est qu'il devient impossible de rajouter quoi que soit après la variable @Buffer et pour cause, celle-ci est "pleine" (Len_Buffer = 128) et ce qui explique pourquoi l'expression (Buffer_Xml) a été tronquée.

    A la fin du script, j'ai tracé le code ascii de chacun des caractères de la variable @Buffer, de la position 1 jusqu'à la position 128, ci-dessous le résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @I=1  @CodeASCII = 67  --> C
    @I=2  @CodeASCII = 108 --> l  (la lettre L minuscule) 
    @I=3  @CodeASCII = 101 --> e
    @I=4  @CodeASCII = 49  --> 1 
    @I=5  @CodeASCII = 61  --> = 
    @I=6  @CodeASCII = 86  --> V
    @I=7  @CodeASCII = 97  --> a
    @I=8  @CodeASCII = 108 --> l   (la lettre L minuscule) 
    @I=9  @CodeASCII = 101 --> e 
    @I=10 @CodeASCII = 117 --> u 
    @I=11 @CodeASCII = 114 --> r 
    @I=12 @CodeASCII = 49  --> 1 
    @I=13 @CodeASCII = 0
    @I=14 @CodeASCII = 0
    @I=15 @CodeASCII = 0
    ....
    .... 
    @I=126 @CodeASCII = 0
    @I=127 @CodeASCII = 0
    @I=128 @CodeASCII = 0
    Jusqu'à la position 12 tout est OK, mais après ça se gâte ! de la position 13 jusqu'à la position 128, il y a que des char(0) ! Je pense que le problème provient de ces char(0) dont je n'arrive pas à m'en défaire !

    Quelqu'un a-t-il déjà rencontré ce problème ? Existe t-il une solution à ce problème ?

    Merci.

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Après plusieurs recherches, il semble que le problème provient de la collation !
    Pour pouvoir remplacer le caractère Null (char(0)), ou plus généralement prendre en compte le caractère Null (char(0)) dans les opérations de comparaison, il faut appliquer à l'expression chaîne une collation de type SQL Server et non pas une collation de type Windows (ne me demandez pas pourquoi !). En effet, il semble que les collations de type Windows ignorent purement et simplement le caractère Null (char(0)). Dans les collations Windows 0x0000 (char(0)) est un caractère indéfini dans les classements et est ignoré dans toute les opérations de comparaison (LIKE, CHARINDEX, PATINDEX, REPLACE, ETC..) cet aspect est bien précisé dans le BOL.

    La solution à mon problème, si elle cela peut intéresser d'autres personnes, est la suivante. Elle consiste à appliquer la collation SQL Server : SQL_Latin1_General_CP1_CI_AS comme suit :
    SET @Buffer = REPLACE(CAST(CONTEXT_INFO() AS VARCHAR(128)) COLLATE SQL_Latin1_General_CP1_CI_AS , CHAR(0), CHAR(32) )

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    DECLARE @varbinBuffer  varbinary(128) 
    DECLARE @Buffer varchar(128) ; 
     
    -- Chemin "Aller" c.à.d  Encodage du CONTEXT_INFO 
    SET @Buffer = 'Cle1=Valeur1'; 
    SET @varbinBuffer = CAST(@Buffer AS varbinary(128)) ; 
    SET CONTEXT_INFO  @varbinBuffer 
     
    -- Chemin "Retour" c.à.d Décodage de CONTEXT_INFO 
    --  Note : Dans l'expression ci-dessous, CHAR(0) représente la caractère Null à remplacer et CHAR(32)  représente le caractère espace pour le remplacement 
    SET @Buffer = REPLACE(CAST(CONTEXT_INFO() AS VARCHAR(128)) COLLATE SQL_Latin1_General_CP1_CI_AS, CHAR(0), CHAR(32) );
    SET @Buffer = LTRIM(RTRIM(@Buffer)); 
    SELECT @buffer As Buffer , '<v>'+ @buffer + '</v>' As Buffer_Xml,  LEN(@Buffer) As Len_Buffer, DATALENGTH(@Buffer) as Datalength_Buffer

    Résultat OK :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Buffer	    Buffer_Xml		Len_Buffer	Datalength_Buffer
    Cle1=Valeur1	<v>Cle1=Valeur1</v>	12	        12
    Remarque : Par curiosité, j'ai testé et vérifié d'autres collations pour remplacer le caractère Null (char(0) ) :
    French_CI_AS *** ne marche pas ! ***
    Latin1_General_CI_AS *** ne marche pas ! ***
    Latin1_General_BIN OK, ça marche

    A+

    PS : Vos avis sur la question sont les bienvenus.
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2003] comportement bizarre fonction hide
    Par jumpman dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 13/06/2012, 23h17
  2. [PHP 5.3] Comportement bizarre de la fonction is_array
    Par renaud26 dans le forum Langage
    Réponses: 7
    Dernier message: 12/05/2011, 16h46
  3. Comportement bizarre de la fonction strlen
    Par clampin dans le forum C
    Réponses: 4
    Dernier message: 30/12/2006, 14h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo