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

SQL Oracle Discussion :

Remplacer une string pour une valeur incrémentée [11g]


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Octobre 2012
    Messages : 33
    Par défaut Remplacer une string pour une valeur incrémentée
    Bonjour,
    J'espère que tout va bien pour vous ce matin, j'aimerai profiter de votre savoir.

    Je souhaiterai remplacer une string (en l'occurrence 'zzz') par un chiffre qui s'incrémente à mesure que ces 3 z apparaissent.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT 'zzz' org FROM DUAL UNION ALL
    SELECT 'pofljzzzpiuiuiizzz' FROM DUAL UNION ALL
    SELECT 'jhjhjkkzzzpoiuzzz' FROM DUAL
    Me retourne évidemment

    zzz
    pofljzzzpiuiuiizzz
    jhjhjkkzzzpoiuzzz




    Serait-il possible que les zzz deviennent des chiffres allant de 1 à ... jusqu'à ce qu'il n'y en ai plus ?
    Donc que ça me retoune :
    1
    poflj2piuiuii3
    jhjhjkk4poiu5



    C'est réalisable ça ?

    Merci pour votre aide

    Henri

  2. #2
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Tu le veux en SELECT ou en UPDATE ?

    J'avais dans l'idée d'utiliser une séquence avec un replace, mais le problème est que le replace ne valide la chaine de remplacement qu'une seule fois..


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT org, REPLACE(org, 'zzz', MaSequence.NEXTVAL) antizzz
    FROM (SELECT 'zzz' org FROM DUAL UNION ALL
    SELECT 'pofljzzzpiuiuiizzz' FROM DUAL UNION ALL
    SELECT 'jhjhjkkzzzpoiuzzz' FROM DUAL)
     
     
    ORG	Antizzz
    zzz	54940
    pofljzzzpiuiuiizzz	poflj54941piuiuii54941
    jhjhjkkzzzpoiuzzz	jhjhjkk54942poiu54942
    Donc a mon avis, il faudra utiliser une fonction qui boucle sur les zzz et qui les transforme un par un en appelant la séquence.

    Si c'est pour un SELECT qui va être utilisé plusieurs fois, il faudrait recréer la séquence à 0 à chaque fois.. ce qui n'est pas top, il faudrait alors utiliser une variable de session (variable de package).

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Octobre 2012
    Messages : 33
    Par défaut
    Salut McM,

    Merci pour ta réponse, c'est pour l'utiliser en SELECT oui, pas en UPDATE.

    Si j'utilise une séquence comme tu le proposes, comment je crée cela ?

    Merci

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    J'ai deux questions : sur quoi vous appuyez vous pour l'ordre de remplacement ?
    Par exemple, pourquoi dans votre exemple ne pas obtenir
    jhjhjkk1poiu2
    poflj3piuiuii4
    5




    et surtout... pourquoi vouloir faire ça ?
    Quel est l’intérêt de tout ça ?

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Octobre 2012
    Messages : 33
    Par défaut
    Bonjour aieeeuuuuu,

    J'ai évidemment simplifié le problème pour ne présenter que l'essentiel, je comprends que vu de l'extérieur ça parait obscur comme but, mais ça a un intérêt certain pour moi. L'expliquer serait trop compliqué et mènerait à embrouiller les esprits.

    L'ordre a effectivement de l'importance, ce serait bien que le 1 soit le premier remplacement et ainsi de suite, et pas le contraire, oui.

    Si ce n'est pas possible, alors tant pis, j'essayerai de m'en sortir différement, mais ça m'aurait été d'une grande aide.

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par h12enri Voir le message
    ce serait bien que le 1 soit le premier remplacement
    Le premier par rapport à quoi ?

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Octobre 2012
    Messages : 33
    Par défaut
    Le premier par rapport à l'ordre que je présente.
    Tu as montré un exemple avec l'ordre inversé, mais je souhaiterai que le 1 commence au premier SELECT statement, et pas à partir du dernier SELECT (comme tu l'as illustré dans ta question initiale).

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    J'imagine que ces données sont dans une table. Et dans une table, il n'y a pas d'ordre des lignes, c'est pourquoi je pose la question.

    Si la numérotation doit se faire selon un ordre précis, alors il faut que cet ordre s'appuie sur quelque chose, comme par exemple une colonne contenant des éléments classables, idéalement uniques (nombres, dates,...)

  9. #9
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Voici comment je le ferais :

    1/ Créer un package qui permet d'avoir une variable de session (v), et une fonction qui pour une chaine renvoie 'zzz' remplacé par la variable v incrémentée.

    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
    CREATE PACKAGE WMC AS
     v NUMBER;
     FUNCTION F (p_chaine IN VARCHAR2) RETURN VARCHAR2;
    END;
    /
    CREATE PACKAGE BODY WMC AS
    FUNCTION F (p_chaine IN VARCHAR2) RETURN VARCHAR2
    IS
     v_chaine VARCHAR2(2000) := p_chaine;
    BEGIN
     WHILE INSTR(v_chaine, 'zzz') > 0
     LOOP
       wmc.v := NVL(wmc.v, 0) + 1;
       v_chaine := SUBSTR(v_chaine, 1, INSTR(v_chaine, 'zzz') - 1) || wmc.v	|| SUBSTR(v_chaine, INSTR(v_chaine, 'zzz') + 3);
     END LOOP;
    	RETURN v_chaine; 
    END;
    END;
    /
    Ensuite, un simple SQL fait l'affaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT org, WMC.f(org) antizzz
    FROM (SELECT 'zzz' org FROM DUAL UNION ALL
    SELECT 'pofljzzzpiuiuiizzz' FROM DUAL UNION ALL
    SELECT 'jhjhjkkzzzpoiuzzz' FROM DUAL)
     
    ORG	ANTIZZZ
    zzz	1
    pofljzzzpiuiuiizzz	poflj2piuiuii3
    jhjhjkkzzzpoiuzzz	jhjhjkk4poiu5
    Penser à réinitaliser la variable de package entre chaque appel (par session), sinon ça continue à s'incrémenter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ORG	ANTIZZZ
    zzz	6
    pofljzzzpiuiuiizzz	poflj7piuiuii8
    jhjhjkkzzzpoiuzzz	jhjhjkk9poiu10
     
    exec wmc.v := 0;
     
    ORG	ANTIZZZ
    zzz	1
    pofljzzzpiuiuiizzz	poflj2piuiuii3
    jhjhjkkzzzpoiuzzz	jhjhjkk4poiu5

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    ou sinon, un truc comme ça (attention, ça pique les yeux )

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    WITH LaTable(i , org) AS (
    	SELECT 1,'zzz' org FROM DUAL UNION ALL
    	SELECT 2,'pofljzzzpiuiuiizzz' FROM DUAL UNION ALL
    	SELECT 3,'jhjhjkkzzzpoiuzzz' FROM DUAL
    ),
    Rec(i, l, org, n) AS (
    	select i, org as l, CAST(org As VARCHAR(50)) AS org, 1 as n
    	from LaTable
    	where i = 1
    	union ALL
    	select 
          LaTable.i,
          LaTable.org, 
          SUBSTR(
                  CASE WHEN INSTR(Rec.org,'zzz' ) > 0 THEN rec.org ELSE LaTable.org END 
                  ,0
                  ,INSTR(
                      CASE WHEN INSTR(Rec.org,'zzz' ) > 0 THEN rec.org ELSE LaTable.org END,
                      'zzz'
                  ) -1
           ) 
            ||
          CAST(Rec.n AS VARCHAR(50))
            ||
          SUBSTR(
                  CASE WHEN INSTR(Rec.org,'zzz' ) > 0 THEN rec.org ELSE LaTable.org END 
                  ,INSTR(
                      CASE WHEN INSTR(Rec.org,'zzz' ) > 0 THEN rec.org ELSE LaTable.org END,
                      'zzz'
                    )
                  +3 
           )
        ,Rec.n + 1
    	from LaTable
    	inner join Rec
    		on LaTable.i = Rec.i + CASE WHEN INSTR(Rec.org,'zzz' ) > 0 THEN 0 ELSE 1 END
    )
    select *
    from rec
    where org not like '%zzz%'

  11. #11
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    ... (attention, ça pique les yeux )
    Bravo pour la performance, mais visuellement, c'est juste immonde !

  12. #12
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    J'avoue ne pas avoir bien compris au premier regard on peut faire du récursif avec du with ?

    Je vais prendre cette requête et l'étudier plus en détail.

  13. #13
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    Citation Envoyé par McM Voir le message
    ... on peut faire du récursif avec du with ?...
    Oui, c'est une nouveauté 11g.

  14. #14
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Octobre 2012
    Messages : 33
    Par défaut
    Formidable les gars! Merci

    Belle peformance, votre aide est précieuse, bravo.

  15. #15
    Membre émérite Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Par défaut
    Fait attention tt de même, si dans la table temp on a des chaines sans la partie recherchée, ca fonctionne pas super.
    Il faut vraiment exclure les chaines non concernées par le traitement.

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

Discussions similaires

  1. [XL-2007] Faire une macro pour une baisse de 2 valeurs consécutives
    Par lepapillon2015 dans le forum Excel
    Réponses: 7
    Dernier message: 16/04/2015, 12h51
  2. Réponses: 4
    Dernier message: 15/10/2009, 13h33
  3. [XL-2007] Afficher une checkbox dans une feuille si une checkbox d'une autre feuille est cochée
    Par JessieCoutas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/08/2009, 13h35
  4. [C#] Comment Splitter une string avec une string ?
    Par ADJ Design dans le forum C#
    Réponses: 12
    Dernier message: 27/07/2006, 12h10
  5. Conseil sur l'extraction d'une string dans une string
    Par Mickey.jet dans le forum Delphi
    Réponses: 3
    Dernier message: 02/06/2006, 14h54

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