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

Langage SQL Discussion :

Remplacer plusieurs valeurs dans le même champ avec une seule update ?


Sujet :

Langage SQL

  1. #1
    Membre éprouvé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 460
    Par défaut Remplacer plusieurs valeurs dans le même champ avec une seule update ?
    bonjour,

    Je souhaite réaliser une opération de publipostage en SQL (remplacer des champs par des valeurs)

    j'ai une table qui est structurée comme ça :

    id : int
    contenu : fulltext
    rule : fulltext
    data : fulltext
    render : fulltext

    exemple

    id : 12
    contenu : "bonjour @@Nom blablablabla comment allez-vous @@LaDate "
    rule : "@@LaDate ,@@Nom"
    data : "ce matin, pierre"

    je souhaite avoir au final dans le champ Render, cette valeur :
    "bonjour Pierre blablablabla comment allez-vous ce matin "




    est-ce possible en SQL (mysql) ?
    En php, ça pourrait se faire car c'est un remplacement de valeur dans une chaine en passant en paramètre un tableau de pattern, et un tableau de valeur.

    J'imaginerai une syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE matable
    SET render=REPLACE (contenu,rule[???],data[???])
    c'est assez la prise de tête car je n'ai pas bcp de marge de manoeuvre, je peux juste reformaté le contenu de rule et de data (ajouter des crochers, séparer par autre chose que des virgules, utiliser une notation en accollade...).
    mon but est de ne pas faire 15 requêtes si dans mon contenu j'ai 15 valeurs à remplacer !

    Je ne sais pas si l'implémentation de tableau de valeur est possible en SQL ni même si Mysql le gère ! Je me souvians avoir vu ça dans oracle et postgres ya longtemps.....)

    Merci pour votre lecture, et ou de votre idée intuitive....

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 167
    Par défaut
    Bonjour,

    Dans Oracle tu peux faire une CTE récursive pour ce besoin, je ne sais pas si tu peux le faire dans MySQL.

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 543
    Billets dans le blog
    10
    Par défaut
    Les CTE ne sont disponibles dans MySQL que depuis la V8

  4. #4
    Membre éprouvé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 460
    Par défaut
    rebonjour,

    par une autre astuce, j'arrive constuire une requête comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UPDATE matable
    SET render=REPLACE (contenu, '@@LaDate','ce matin')
    ,render=REPLACE (contenu, ',@@Nom','pierre')
    ,render=REPLACE (contenu, ',@@Salutation','Bonne journée')
    WHERE id=12

    Mais problème :

    les 2 premières instructions set sur le champs Render sont écrasées par la dernier render
    Je ne sais pas si c'est un problème de syntaxe ou bien si le SQL ne permet pas de faire ceci :
    si a=0 au départ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update matable set a=a+1, a=a+1, a=a+1
    pour avoir 3 dans a au final

    votre avis ?

    ps : pitié, ne me dites pas que je dois générer une requête horrible imbriquée du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    update matable
    set render=(replace(replace(replace(contenu, '@@LaDate','ce matin'),@@Nom','pierre'),@@Salutation','Bonne journée'))

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 167
    Par défaut
    Comment feras-tu s'il y a un nombre variables de valeurs à remplacer par id? C'est pour cela qu'il faut faire du récursif. Si pas dispo alors je suppose que tu peux faire une construction itérative?

  6. #6
    Membre éprouvé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 460
    Par défaut
    l'instruction REPLACE remplace bien toutes les occurrences recherchées, non ?

  7. #7
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 167
    Par défaut
    Si tu as 3 valeurs à remplacer, tu feras 3 REPLACE imbriqués, mais si par exemple tu as 10 paramètres @@, tu devras faire 10 REPLACE imbriqués. Ca ne fonctionnera pas pour toutes tes lignes.

  8. #8
    Membre éprouvé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 460
    Par défaut
    sans penser à la charge serveur mais plutôt à la simplicité de lecture du code, pour l'instant pour que ça fonctionne, j'avais pensé mettre 20 replaces puisque j'ai 20 valeurs @@ différents à remplacer.
    je sais que c'est stupide de faire 19 replaces si seulement 1 seule existe dans la chaîne mais au moins c'est fonctionnel...

  9. #9
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 167
    Par défaut
    Oui si tu connais d'avance le nom des paramètres ça fonctionnera, même si en effet ce n'est pas très propre. Un exemple de requête récursive (dans Oracle) qui te le fais plus "dynamiquement":

    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
    with t(id, contenu, rule, data)
    as (select 12, 'bonjour @@Nom blablablabla comment allez-vous @@LaDate', '@@LaDate ,@@Nom', 'ce matin, pierre' from dual
        union all
        select 13, 'bonjour @@Nom blablablabla comment allez-vous @@LaDate à @@Lieu', '@@LaDate ,@@Nom ,@@Lieu', 'ce soir, paul, Paris' from dual
        ),
       v (id, contenu, rule, data, cnt, lvl)
    as (
    select id, replace(contenu, trim(regexp_substr(rule, '[^,]+')), regexp_substr(data, '[^,]+')), rule, data, regexp_count(rule, '[^,]+'), 1
        from t
        union all
        select id, replace(contenu, trim(regexp_substr(rule, '[^,]+', 1, lvl+1)),  regexp_substr(data, '[^,]+', 1, lvl+1)), rule, data, cnt, 1 + lvl
        from v
        where lvl < cnt
    )
    select * from v
    where lvl = cnt
    order by id, lvl;
     
     
    12	bonjour  pierre blablablabla comment allez-vous ce matin	@@LaDate ,@@Nom	ce matin, pierre	2	2
    13	bonjour  paul blablablabla comment allez-vous ce soir à  Paris	@@LaDate ,@@Nom ,@@Lieu	ce soir, paul, Paris	3	3

  10. #10
    Membre éprouvé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 460
    Par défaut
    je viens d'y penser, mysql ne gère pas les regex pour les mots entiers ?? à moins que ce ne soit que pour les lettres uniquement

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 986
    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 986
    Billets dans le blog
    6
    Par défaut
    Le plus simple est d'utiliser une table de correspondance avec 2 colonnes : la valeur à modifier et la valeur de remplacement, puis de faire un UPDATE avec jointure en utilisant le REPLACE.
    Si votre version de SGBD supporte les CTE, utilisez une CTE pour cette table de correspondance.

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

  12. #12
    Membre éprouvé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 460
    Par défaut
    bonjour,

    merci pour vos idées.

    quelqu'un a-t-il une idée du coût serveur (charge de calcul) d'une requête comme ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    update matable
    set render=(replace(replace(replace(contenu, '@@LaDate','ce matin'),@@Nom','pierre'),@@Salutation','Bonne journée'))
    un replace dans un replace dans un replace, ça crée une pile mémoire, donc couteux ?
    si c'est une ligne de 20 replace imbriqués, est-ce dangereux ?

    côté code, je peux "embelliser" l'écriture de la requête avec des retours chariot (afin de facilier la maintenance du code par autrui)

Discussions similaires

  1. Plusieurs valeurs dans un même champ
    Par fidecourt dans le forum Outils
    Réponses: 2
    Dernier message: 30/01/2013, 00h03
  2. [AC-2010] saisir plusieurs valeurs dans un même champ
    Par pbpb76 dans le forum Access
    Réponses: 1
    Dernier message: 17/03/2011, 10h34
  3. Plusieurs valeurs dans un même champ
    Par cambio dans le forum Modélisation
    Réponses: 3
    Dernier message: 20/11/2009, 11h31
  4. [MySQL] Insertion de plusieurs valeurs dans un même champ de MySQL
    Par Monsieur K dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 20/09/2009, 15h50
  5. [A-03]plusieurs valeurs dans le même champ
    Par eldjuju dans le forum IHM
    Réponses: 1
    Dernier message: 12/03/2009, 17h33

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