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 :

La fonction REPLACE ne fonctionne pas sur un cas précis ?


Sujet :

SQL Oracle

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 4
    Points
    4
    Par défaut La fonction REPLACE ne fonctionne pas sur un cas précis ?
    Bonjour tous,

    Je ne me débrouille pas trop mal en SQL, mais je sèche cette fois-ci :
    Après avoir fait des INSERT dans ma table, je souhaite faire un UDPATE sur le champ PARAM_DATE pour remplacer des variable par un jour de l'année au format DD/MM/YYYY, les requêtes UPDATE que fonctionnent pour toutes les variables sauf la variable "jour-1" et je n'arrive pas à saisir pourquoi. Ca avait pourtant marché au début, j'ai dû modifier quelque chose pour que ça ne fonctionne plus ensuite ...

    Voici les données de ma table :

    NREQ, NOM_SQL, JOUR_MOIS PARAM_DATE
    SEC3-DE, SEC3_R09031301_M01_DE.SQL, 01, jour-1 jour-1 DE
    SEC3-DCT, SEC3_R09031301_M01_DCT.SQL, 01, jour-1 jour-1 DCT
    181, 181_R09011602_M02.sql, 02, '*' sem_pre_deb sem_pre_fin '*' '*'
    200_ELD, R11110401_M01.sql, 05, 04/2014 200_Comptes_ELD.txt
    187, 187_R04589602_M02.sql, 02, '*' today '*' '*'

    Et les requêtes UPDATE :

    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
    -- mettre à jour la variable 'today'
    update MCO_LANCE_REQUETES_RAD a
    set a.PARAM_DATE = replace(a.PARAM_DATE, 'today',  to_char(to_date(jour_mois||'&&mois'||'&&annee',  'DD/MM/YYYY'),'DD/MM/YYYY'))
    where a.PARAM_DATE like '%today%';
    
    -- mettre à jour la variable 'jour-1'
    update MCO_LANCE_REQUETES_RAD a
    set a.PARAM_DATE = replace(a.PARAM_DATE, 'jour-1',  to_char(to_date(jour_mois||'&&mois'||'&&annee',  'DD/MM/YYYY')-1,'DD/MM/YYYY'))
    where a.PARAM_DATE like to_char('%jour-1%');
    
    -- mettre à jour la variable sem_pre_deb 
    update MCO_LANCE_REQUETES_RAD a
    set a.PARAM_DATE = replace(a.PARAM_DATE, 'sem_pre_deb',  to_char(to_date(jour_mois||'&&mois'||'&&annee',  'DD/MM/YYYY')-7,'DD/MM/YYYY'))
    where a.PARAM_DATE like '%sem_pre_deb%';
    
    -- mettre à jour la variable sem_pre_fin
    update MCO_LANCE_REQUETES_RAD a
    set a.PARAM_DATE = replace(a.PARAM_DATE, 'sem_pre_fin',  to_char(to_date(jour_mois||'&&mois'||'&&annee',  'DD/MM/YYYY')-1,'DD/MM/YYYY'))
    where a.PARAM_DATE like '%sem_pre_fin%';
    Toutes les requêtes UPDATE fonctionnent sauf pour celle où la variable est 'jour-1' , je me demandais si c'était le " -1" de la variable qui posait problème et ça n'est apparemment pas ça qui pose problème (j'ai enlevé le "-1" pour voir, l'erreur reste la même)
    Le message d'erreur que j'ai est la suivante :
    ORA-01861: le littéral ne concorde pas avec le format chaîne de caractères


    Alors, je viens vers vous vous demander ce qui coince dans ma requête UPDATE ? ...

    Par avance, merci ... !

    Pour vous aider à tester, voici un petit jeu de données :
    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
     
    CREATE TABLE MCO_LANCE_REQUETES_RAD
    (
      NREQ        VARCHAR2(50 BYTE)                 NOT NULL,
      NOM_SQL     VARCHAR2(50 BYTE)                 NOT NULL,
      JOUR_MOIS   VARCHAR2(4 BYTE)                  NOT NULL,
      EXEC        VARCHAR2(3 BYTE)                  NOT NULL,
      PARAM_DATE  VARCHAR2(150 BYTE)                NOT NULL
    ); 
     
     
    INSERT INTO MCO_LANCE_REQUETES_RAD VALUES('SEC3-DE','SEC3_R09031301_M01_DE.SQL','04','O','jour-1 jour-1 DE');
    INSERT INTO MCO_LANCE_REQUETES_RAD VALUES('SEC3-DCT','SEC3_R09031301_M01_DCT.SQL','04','O','jour-1 jour-1 DCT');
    INSERT INTO MCO_LANCE_REQUETES_RAD VALUES('121','121_R05112502_M05.sql','05','O','2014 04');
    INSERT INTO MCO_LANCE_REQUETES_RAD VALUES('176','R08121501_M04.sql','05','O','2014 04 ''*''');
    INSERT INTO MCO_LANCE_REQUETES_RAD VALUES('181','181_R09011602_M02.sql','05','O','''*'' sem_pre_deb sem_pre_fin ''*'' ''*''');
    INSERT INTO MCO_LANCE_REQUETES_RAD VALUES('SEC11_Soldes physiques','SEC11_R10100401.sql','05','O','jour-1');
    INSERT INTO MCO_LANCE_REQUETES_RAD VALUES('191','191_R11031801_M01_avec_index.sql','06','O','today 30/04/2014');

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Le to_char dans le filtre à la ligne #9 est inutile, mais je ne pense pas qu'il soit à l'origine du problème.

    Il faudrait surtout savoir aussi ce qu'il y a dans &&mois et &&annee, sinon impossible d'évaluer quoi que ce soit.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 4
    Points
    4
    Par défaut
    Merci Waldar,

    En invite, je saisis pour &&mois : 06
    et && annee : 2014

    Et au format type : String pour les deux variables mois et annee.
    J'ai également essayé au format Integer (bien que ça n'a rien à faire dans un to_char), sans succès.

    Nom : Capture PopUp.jpg
Affichages : 368
Taille : 140,4 Ko

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Et bien il manque les "/" indiqués dans la construction du format de date.
    C'est vrai qu'Oracle DB est permissif sur les séparateurs, mais le message d'erreur va quand même dans ce sens donc autant être précis :

    Que donne cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select PARAM_DATE
         , jour_mois || '&&mois' || '&&annee' as conc
         , to_date(jour_mois || '&&mois' || '&&annee',  'DDMMYYYY') as conc_dt
         , replace(PARAM_DATE, 'jour-1', to_char(to_date(jour_mois || '&&mois' || '&&annee',  'DDMMYYYY') - 1, 'DD/MM/YYYY'))
      from MCO_LANCE_REQUETES_RAD
     where PARAM_DATE like '%jour-1%';

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 4
    Points
    4
    Par défaut
    Bonjour Waldar,

    J'avais déjà essayé cette requête sans succès, l'erreur est la suivante :

    Nom : AnotherError.jpg
Affichages : 338
Taille : 73,3 Ko


    Même en rajoutant des slashs entre les variables, j'ai le même message d'erreur :
    ORA-01839: le quantième n'est pas valide pour le mois indiqué

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT PARAM_DATE
         , jour_mois || '&&mois' || '&&annee' AS conc
         , to_date(jour_mois ||'/' || '&&mois' ||'/'|| '&&annee',  'DD/MM/YYYY') AS conc_dt
         --, REPLACE(PARAM_DATE, 'jour-1', to_char(to_date(jour_mois ||'/'||'&&mois'||'/'||'&&annee',  'DD/MM/YYYY') - 1, 'DD/MM/YYYY'))
      FROM MCO_LANCE_REQUETES_RAD
     WHERE PARAM_DATE LIKE '%jour-1%';
    Je sèche toujours autant ... !

  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
    Points : 13 092
    Points
    13 092
    Par défaut
    bonjour,

    N'auriez vous pas des 31 dans la colonne jour_mois par hasard ?

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 4
    Points
    4
    Par défaut
    Bravo aieeeuuuuu !!

    J'aurais du m'en douter au vu du message d'erreur ... !!
    Effectivement, j'ai des 31, et bien sûr quand je mets le mois '06' ça ne marche pas parce qu'il n'y a pas de 31 au mois de juin !!

    Il va falloir que je trouve une parade pour contourner cette problématique, car il faudra quand même rentrer des mois de moins de 31 jours.

    Merci quand même à vous !

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par vinzmeister Voir le message
    Je sèche toujours autant ... !
    Mais vous évitez soigneusement l'essentiel, vous n'affichez pas le contenu de votre concaténation !!!!!!! je m'arrête là mais dans ma tête il en manque quelques dizaines

    Que donne cette requête ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT PARAM_DATE
         , jour_mois || '&&mois' || '&&annee' AS conc
      FROM MCO_LANCE_REQUETES_RAD
     WHERE PARAM_DATE LIKE '%jour-1%';
    Une minuscule fonction que vous servira certainement :
    http://www.developpez.net/forums/d13...e/#post7139414

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 4
    Points
    4
    Par défaut
    Excusez moi Waldar )

    Le résultat de votre requête donne :
    Nom : 2014-06-12_084920.jpg
Affichages : 332
Taille : 49,0 Ko

    Votre lien donnant sur une fonction m'a donné une idée pour palier le problème du jour 31 qui déclenche une erreur de la fonction to_date si le paramètre mois n'est pas un mois de 31 jours (comme février, avril, etc ..).

    J'ai fait un début d'algorithme (à la sauce Toad, sur la base de votre exemple adapté au format Toad que j'ai pu récupérer sur le Web.
    Je ne suis malheureusement pas assez compétent pour palier le problème du mois de février :
    - ramener le jour 30 à 29 ou 28 selon l'année,
    - si 29, laisser le jour 29 ou le ramener à 28.

    Pouvez-vous m'aider sur ce point ?

    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 OR REPLACE FUNCTION CISADM.decremente_jour(jour IN NUMBER, mois in number, annee in number) RETURN DATE IS
    jourVar NUMBER;
    BEGIN
    jourVar:=jour-1;
    if (jour=30 and mois <> 02 )
    then
    null;-- gestion du mois bissextile (si 30 alors le ramener à 28 ou 29 selon l'année)
    end if;
    RETURN to_date(jourVar||mois||annee, 'DD/MM/YYYY');
    END decremente_jour; -- mettre à jour la variable 'jour-1'
    /
     
     
    -- la fonction serait utilisé dans l'update :
     
    update MCO_LANCE_REQUETES_RAD a
    set a.PARAM_DATE = replace(a.PARAM_DATE, 'jour-1',  decremente_jour(jour_mois, &&mois , &&annee ) )
    where a.PARAM_DATE like to_char('%jour-1%');
    De plus, j'ai testé la fonction avec &&mois=06 et l'année courante, j'ai le message d'erreur suivant :

    Nom : 2014-06-12_103303.jpg
Affichages : 369
Taille : 46,6 Ko

    L'erreur parle du format de la chaîne, j'ai alors utilisé la fonction to_char pour voir, le message d'erreur reste :
    Nom : 2014-06-12_103932.jpg
Affichages : 323
Taille : 49,4 Ko

    Peut-être parce que j'appelle la fonction d'une mauvaise façon ...

  10. #10
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    bonjour,

    pourquoi n'utilisez-vous pas les intervales pour enlever un jour ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select current_date, current_date - interval '1' day
    from dual

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 4
    Points
    4
    Par défaut
    Bonjour Punkoff,

    Je ne connaissais pas cela, c'est utile.

    Malheureusement, je ne pense pas pouvoir l'utiliser car je fais une concaténation de jour (qui est une donnée en table), de mois et d'année (donnée en paramètre prompt par l'utilisateur ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    -- mettre à jour la variable 'jour-1'
    UPDATE MCO_RAD.MCO_LANCE_REQUETES_RAD a
    SET a.PARAM_DATE = replace(a.PARAM_DATE, 'jour-1', to_date(jour_mois||'&&mois'||'&&annee', 'DD/MM/YYYY')-1)
    where a.PARAM_DATE like '%jour-1%';
    La fonction to_date plante quand jour_mois = 31 et que je saisis &&mois = 06, car 31/06 n'existe pas...

  12. #12
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par vinzmeister Voir le message
    Peut-être parce que j'appelle la fonction d'une mauvaise façon ...
    À votre place, je me débrouillerai pour corriger ou faire corriger les données en amont : garbage IN => garbage OUT.

    Néanmoins, votre fonction est remplie d'erreurs :
    1. Elle reçoit des nombres et vous lui envoyez des varchar => vous forcez une conversion implicite (ce qui est mal).
    2. Vous concaténez des nombres => deuxième conversion implicite (ce qui est mal).
    3. Dans le format du to_date, il contient des "/" mais avec des nombres en entrée je ne vois pas d'où vont venir ces "/".


    Et quand vous avez une erreur de format dans un to_date, il FAUT afficher la valeur de la chaîne avec dbms_output dans le bloc d'exception, afin de comprendre d'où vient l'erreur.

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 4
    Points
    4
    Par défaut
    Merci Walda pour vos remarques.

  14. #14
    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
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Si vous voulez ramener les 31 au dernier jour du mois, il serait peut-être plus simple de s'appuyer sur la fonction d'ajout de mois -qui gérera la fin de mois tout seule- en partant d'un mois de 31 jours, comme le mois de janvier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT 
        ADD_MONTHS('31-Jan-01', 1) As Fevrier_Bisextile
        ,ADD_MONTHS('31-Jan-01', 1) AS Fevrier_Commune
        ,ADD_MONTHS('31-Jan-01', 3) AS Avril_30Jours
    FROM dual;
    FEVRIER_BISEXTILE 	FEVRIER_COMMUNE 	AVRIL_30JOURS
    February, 29 2000  	February, 28 2001  	April, 30 2001 
    
    Dans votre cas, il suffirait donc de construire la date comme ceci : [jour_mois-Jan-&&annee], et d'ajouter [&&mois - 1] mois.

Discussions similaires

  1. La fonction replace() ne fonctionne pas
    Par bernidupont dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 25/03/2013, 18h13
  2. Réponses: 2
    Dernier message: 31/05/2010, 13h23
  3. fonction confirm() qui ne fonctionne pas sur IE7
    Par JackBeauregard dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 14/06/2008, 09h47
  4. commande replace fonctionne pas sur variable SQL?
    Par doogybreton dans le forum VBA Access
    Réponses: 5
    Dernier message: 24/01/2008, 16h30
  5. Fonction DISTINCT ne fonctionne pas sur une date
    Par cramouille dans le forum Access
    Réponses: 5
    Dernier message: 25/10/2006, 15h42

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