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

Développement SQL Server Discussion :

Modifier du xml dans un varchar avec une regex


Sujet :

Développement SQL Server

  1. #1
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 192
    Points : 28 073
    Points
    28 073
    Par défaut Modifier du xml dans un varchar avec une regex
    Bonjour à tous,

    Petite problématique du jour, dans une modification en masse de données dans une base SQL Server par scripts sql (sinon c'est pas marrant), je butte sur une table qui contient une colonne de type varchar(max). Cette colonne contient en réalité des données formatées en xml selon le schéma suivant :
    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
    <A>
      <Bs>
        <B Atr1="6555" Atr2="3150" Atr3="0" />
        <B Atr1="6556" Atr2="3150" Atr3="0" />
        <B Atr1="6705" Atr2="3150" Atr3="0" />
    	...
      </Bs>
      <Cs>
        <C Atr1="2536" Atr2="3151" Atr3="0/>
        <C Atr1="2584" Atr2="3151" Atr3="0 />
        <C Atr1="3072" Atr2="3151" Atr3="0" />
    	...
      </Cs>
      <Ds>
        <D Atr1="2537" Atr2="3152" Atr3="0" />
        <D Atr1="2585" Atr2="3152" Atr3="0" />
        <D Atr1="3073" Atr2="3152" Atr3="0" />
    	...
      </Ds>
    </A>
    Les attributs Atr1 et Atr2 sont en réalité des int qui représentent des identifiants. Je dois les modifier pour leur rajouter une valeur fixe à chacun, la même pour tous.
    La colonne n'étant pas typée XML, je ne peux pas utiliser les fonctions dédiées, qui me semblent bien compliquées à mettre en œuvre d'ailleurs.

    Ma question est, étant donné que la colonne est un varchar, n'y aurait-il pas moyen de faire mumuse avec simplement du replace et une bonne regex ?

    PS : j'agis sous pression et dans l'urgence, je n'arrive plus à réfléchir correctement
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  2. #2
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 091
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 091
    Points : 8 194
    Points
    8 194
    Billets dans le blog
    17
    Par défaut
    Je ne connais pas MS SQL Server, mais avec MySQL pour préfixer chaque nombre de Atr1 ou Atr2 avec 9999 tu peux faire :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SET @xml = '
    	<A>
    		<Bs>
    			<B Atr1="6555" Atr2="3150" Atr3="0" />
    			<B Atr1="6556" Atr2="3150" Atr3="0" />
    			<B Atr1="6705" Atr2="3150" Atr3="0" />
    			...
    		</Bs>
    		...
    	</A>';
     
    SELECT ALL REGEXP_REPLACE(@xml, '(Atr[12])="(\\d+)"', '$1="9999$2"');

    Donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <A>
    	<Bs>
    		<B Atr1="99996555" Atr2="99993150" Atr3="0" />
    		<B Atr1="99996556" Atr2="99993150" Atr3="0" />
    		<B Atr1="99996705" Atr2="99993150" Atr3="0" />
    		...
    	</Bs>
    	...
    </A>
    En espérant que tu aies un équivalent à REGEXP_REPLACE() sous MS SQL
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  3. #3
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 192
    Points : 28 073
    Points
    28 073
    Par défaut
    Et tout le soucis est là, il ne s'agit pas de préfixer, mais bien d'additionner une valeur à la valeur existante.

    De plus je me rend compte en continuant d'investiguer, que je peux parfois avoir des attributs qui sont vides <B Atr1="" Atr2="3150" Atr3="0" />. Dans ce cas, il faut additionner mais il faut laisser l'attribut vide.
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 759
    Points : 52 540
    Points
    52 540
    Billets dans le blog
    5
    Par défaut
    Il y avait des erreurs dans ton jeu de travail... des " manquants !!!

    donc :

    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
    DECLARE @STRING VARCHAR(max) = N'
    <A>
      <Bs>
        <B Atr1="6555" Atr2="3150" Atr3="0" />
        <B Atr1="6556" Atr2="3150" Atr3="0" />
        <B Atr1="6705" Atr2="3150" Atr3="0" />
      </Bs>
      <Cs>
        <C Atr1="2536" Atr2="3151" Atr3="0" />
        <C Atr1="2584" Atr2="3151" Atr3="0" />
        <C Atr1="3072" Atr2="3151" Atr3="0" />
      </Cs>
      <Ds>
        <D Atr1="2537" Atr2="3152" Atr3="0" />
        <D Atr1="2585" Atr2="3152" Atr3="0" />
        <D Atr1="3073" Atr2="3152" Atr3="0" />
      </Ds>
    </A>'
    Transtype en XML et utilise la décomposition par niveau dont les noms des balises sont variables :

    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
    21
    22
    DECLARE @XML XML = CAST(@STRING AS xml);
     
    WITH
    T1 AS
    (
    SELECT xdata.value('fn:local-name(.)', 'NVARCHAR(256)') AS LVL1, 
           xdata.query('./*') AS x1
    FROM @XML.nodes('A/*') AS Txml(xdata)
    ),
    T2 AS
    (
    SELECT LVL1, xdata2.value('fn:local-name(.)', 'NVARCHAR(256)') AS LVL2, 
           xdata2.query('.') AS x2
    FROM   T1
           CROSS APPLY x1.nodes('././*') AS Txml2(xdata2)
    )
    SELECT LVL1, LVL2, x2,
           xdata3.value('@Atr1', 'int') AS ATR1_value,
           xdata3.value('@Atr2', 'int') AS ATR2_value,
           xdata3.value('@Atr3', 'int') AS ATR3_value
    FROM   T2
           CROSS APPLY T2.x2.nodes('./././*') AS Txml3(xdata3);

    Ce qui donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    LVL1  LVL2  x2                                        ATR1_value ATR2_value ATR2_value  
    ----- ----- ----------------------------------------- ---------- ---------- ----------
    Bs    B     <B Atr1="6555" Atr2="3150" Atr3="0" />    6555       3150       0
    Bs    B     <B Atr1="6556" Atr2="3150" Atr3="0" />    6556       3150       0
    Bs    B     <B Atr1="6705" Atr2="3150" Atr3="0" />    6705       3150       0
    Cs    C     <C Atr1="2536" Atr2="3151" Atr3="0" />    2536       3151       0
    À la fin tu n'as plus qu'à recomposer en XML après changement des valeurs

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. Réponses: 4
    Dernier message: 14/01/2008, 00h15
  2. [XI] Calcul de valeurs dans un graphique avec une periode de temps
    Par campia dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 23/04/2007, 09h17
  3. Ecriture dans un fichier avec une applet Java
    Par foued_scorpion dans le forum Applets
    Réponses: 1
    Dernier message: 25/10/2006, 11h30
  4. [D6 => XML] Récupération de données avec une boucle.
    Par Bason_sensei dans le forum Delphi
    Réponses: 1
    Dernier message: 23/05/2006, 13h50
  5. enregistrer dans un fichier avec une appli mdi
    Par ferrari dans le forum C++Builder
    Réponses: 4
    Dernier message: 05/05/2002, 15h17

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