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 :

Calcul dans un regexp_replace


Sujet :

SQL Oracle

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2017
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Calcul dans un regexp_replace
    Bonjour,

    Je dispose d'une base de données dans laquelle j'ai une colonne qui contient des comptes rendus textuels avec des dates(il peut très bien y avoir 1 seule date comme 10) sous la forme JJ/MM/AAAA.
    Mon objectif serait de modifier toutes les dates en leur enlevant un certain nombre de jours.

    Comme indiqué dans l'intitulé je pensais faire un update avec l'utilisation de regexp_replace comme suivant:

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UPDATE ma_table SET compterendu = regexp_replace(compterendu,'([0-9]+/[0-9]+/[0-9]+)','/1'-300);

    J'obtiens l'erreur ORA-01722: invalid number
    J'ai essayé de rajouter des to_date, to_char j'obtiens toujours la même erreur.

    Ma question est donc la suivante, est-il possible de faire des calculs arithmétiques dans un regexp_replace?
    Dans le cas contraire quelle serait la meilleure option à prendre pour résoudre ce problème?

    En vous remerciant par avance de votre aide!

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

    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
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Premièrement, ce n'est pas '/1' mais '\1' qu'il faut mettre.

    Et ce n'est pas possible de faire des calculs : le second paramètre de REGEXP_REPLACE est un string.
    Les \1.. sont gérés dans la fonction REGEXP, donc impossible de faire de l'arithmétique avant.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    Bonjour,

    Tout d'abord vous pouvez tester que vous obtenez bien le résultat obtenu en passant par un SELECT et pas par un UPDATE directement...

    Ensuite, rapidement pour vous donner une piste : je ferais plutôt avec un REGEXP_SUBSTR pour extraire la date, et je ferais mes calculs par la suite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT TO_DATE(REGEXP_SUBSTR('Compte-rendu du 20/11/2017, à 8h', ('(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}')), 'DD/MM/YYYY') - 300
    FROM DUAL
    (j'en ai profité pour proposer une meilleure REGEX, pas la peine de réinventer la roue)

    Je prends comme hypothèse que vous n'avez qu'une date par ligne dans la BDD.
    Vous indiquez qu'"il peut très bien y avoir 1 seule date comme 10". Si c'est dans le même champ, ma requête ci-dessus n'ira pas.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2017
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonjour à vous deux,

    Merci pour vos réponses.

    @McM : effectivement c'est une erreur de recopie, j'utilisais bien '\1'.

    @Emmanuel R : malheureusement j'ai bien plusieurs dates. Il est tout de même possible de récupérer plusieurs dates sur un même champs en combinant REGEX_SUBSTR avec un CONNECT BY LEVEL.

  5. #5
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Je dirais sans mâcher les mots que les documentations d'Oracle sur regexp_replace() partout sont, sinon trompeuses, tout au moins pas de l'histoire entière - et l'histoire, il me semble, n'est pas si jolie!

    Typiquement, elles disent
    Citation Envoyé par https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions137.htm#SQLRF06302
    replace_string can be of any of the datatypes CHAR, VARCHAR2, NCHAR, NVARCHAR2, CLOB, or NCLOB. If replace_string is a CLOB or NCLOB, then Oracle truncates replace_string to 32K. The replace_string can contain up to 500 backreferences to subexpressions in the form \n, where n is a number from 1 to 9.
    Soit.

    En principe et conceptuellement parlant basé sur leurs mots, --- supposant la date soit du format de dd/mm/yyyy, et le pattern peut s'améliorer sans cesse surement, --- on peut faire ça
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE ma_table SET compterendu = regexp_replace(compterendu,'\b([0-9]{2}/[0-9]{2}/[0-9]{4})\b',
        to_char(to_date('\1', 'dd/mm/yyyy')-300, 'dd/mm/yyyy')
    ); -- erreur ORA 01858
    Mais, ça donne l'erreur ORA-01858...

    Pourtant, on peut faire une analogie jusqu'au niveau de fonctions deux fois imbriqués, comme par exemple:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE ma_table SET compterendu = regexp_replace(compterendu,'\b([0-9]{2}/[0-9]{2}/[0-9]{4})\b',
        concat(concat('\1', 'abc'), 'zyx')
    ); -- acceptable
    et c'est très acceptable.

    Je ne suis pas sûr si c'est un bogue ou une mal-représentation, volontaire ou pas, des documentations, mais ça se comporte comme ça et c'est fâcheux.

    Si ça ne marche pas de la façon en une ligne, on peut, bien entendu, faire un petit bloque pl/sql pour ce but de mise-à-jour.

    Voilà ce que je vois sur le sujet.

Discussions similaires

  1. Réponses: 3
    Dernier message: 20/09/2005, 21h07
  2. Calcul dans un triggers : problème du +
    Par eXiaNazaire dans le forum Oracle
    Réponses: 3
    Dernier message: 07/01/2005, 10h14
  3. Recuperer un champ calculé dans une variable....
    Par vijeo dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 21/12/2004, 14h57
  4. Calcul dans des champs de saisie
    Par leeloo076 dans le forum ASP
    Réponses: 4
    Dernier message: 07/04/2004, 10h09
  5. calcul dans une requête
    Par blaz dans le forum Langage SQL
    Réponses: 8
    Dernier message: 22/12/2003, 10h31

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