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

PL/SQL Oracle Discussion :

Warning plw-07202 lors de la conversion d'une date dans un insert


Sujet :

PL/SQL Oracle

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut Warning plw-07202 lors de la conversion d'une date dans un insert
    Bonjour,

    j'essaye d'éviter un warning lorsque je recopie une table dans une autre, avec une petite conversion en route.

    je dispose de deux tables :
    * tab1("myid" : NUMBER(3), "mydate" : DATE)
    * tab2("myid" : NUMBER(3), "mydate" : NUMBER(8)), où la date est sous forme YYYYMMDD

    Je veux recopier tab2 vers tab1, j'ai donc une requête du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO tab1(myid, mydate)
         SELECT myid, TODATE_(mydate, 'yyyymmdd') FROM tab2
    Mais à la compilation, j'obtiens un warning plw-07202 : "le type bind entrainera la conversion à partir du type de la colonne".

    D'après ce que j'ai compris, ce warning vise à éviter l'appel de fonctions à l'intérieur de requêtes SQL, car on risque de ne pas utiliser les index. Par exemple dans une requête du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT myid
    FROM tab1
    WHERE TO_NUMBER(TO_CHAR(mydate, 'yyyymmdd')) = 20080101
    si tab1 est indexée sur le champ mydate, on n'utilisera pas l'index car la colonne sera d'abord convertie en number (et on ne dispose pas d'index sur mydate convertie en nombre).

    Mais dans mon cas, la seule solution que je vois pour ne pas appeler TO_DATE à l'intérieur de ma requête, est de :
    - faire une première requête de select from tab2, avec un bulk collect dans un tableau
    - parcourir ce tableau et le recopier en convertissant la date à l'intérieur d'un nouveau tableau
    - insérer le nouveau tableau créé via un forall à l'intérieur de la table tab1

    Il me semble que ça revient à beaucoup compliquer la requête, et probablement diminuer les performances....?

    Si vous avez un avis ou une autre idée pour éviter ce warning je suis preneur

    Merci

  2. #2
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Pour éviter ce warning, il faut simplement faire (si j'ai bien compris ton problème):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO tab1(myid, mydate)
         SELECT myid, TO_DATE(TO_CHAR(mydate), 'yyyymmdd') FROM tab2

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    Merci pour ta réponse. Effectivement j'avais oublié le TO_CHAR qui évite une conversion implicite, mais ça ne résoud pas le problème...

    En simplifiant le problème, le warning est simplement provoqué par l'instruction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO tab1(mydate)
        VALUES (TO_DATE('20080101', 'YYYYMMDD'));
    Le simple appel à TO_DATE à l'intérieur d'une requête entraine la warning. Je comprends parfaitement l'intérêt si on appelle TO_DATE à l'intérieur de la clause WHERE, car on n'utilisera pas l'index, mais dans un INSERT je ne vois pas...

  4. #4
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Tu exécutes ce code avec quel outil ?

    [EDIT]Tom Kyte traite ce problème :
    http://asktom.oracle.com/pls/asktom/...94300346290510

    Voici un petit test :
    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
    SQL> create or replace procedure p1 is
      2  begin
      3    insert into t1 (mydate) values (to_date('20080101', 'YYYYMMDD'));
      4  end;
      5  /
    Procedure created.
     
    SQL> exec dbms_warning.add_warning_setting_cat('ALL', 'ENABLE', 'SESSION')
    PL/SQL procedure successfully completed.
     
    SQL> create or replace procedure p1 is
      2  begin
      3    insert into t1 (mydate) values (to_date('20080101', 'YYYYMMDD'));
      4  end;
      5  /
    SP2-0804: Procedure created with compilation warnings
     
    SQL> show err
    Errors for PROCEDURE P1:
     
    LINE/COL ERROR
    -------- -----------------------------------------------------------------
    3/35     PLW-07202: bind type would result in conversion away from column
             type
     
    3/55     PLW-07202: bind type would result in conversion away from column
             type
     
    SQL> create or replace procedure p1 is
      2    d date;
      3  begin
      4    d := to_date('20080101', 'YYYYMMDD');
      5    insert into t1 (mydate) values (d);
      6  end;
      7  /
    Procedure created.
    [/EDIT]

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    J'utilise SQL developper.

    Effectivement, la solution serait de "sortir" la fonction TO_DATE de la requête SQL. Mais comme je le disais, au lieu d'un code tu type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO tab1(myid, mydate)
         SELECT myid, TO_DATE(TO_CHAR(mydate, 'yyyymmdd') )FROM tab2
    J'aurai quelque chose comme ça, où toto1 est un tableau de (NUMBER, NUMBER) et toto2 un tableau de (NUMBER, DATE) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT myid, mydate FROM tab2 BULK COLLECT INTO toto1
     
    FOR i IN toto1.FIRST .. toto1.LAST LOOP
       toto2(i) := toto1.myid, TO_DATE(TO_CHAR(toto1.mydate, 'YYYYMMDD'))
    END LOOP
     
    FORALL i IN toto2.FIRST .. toto2.LAST
       INSERT INTO tab1(myid, mydate) VALUES (toto2(i).myid, toto2(i).mydate)
    Vu les millions de ligne que j'ai à traiter, j'ai peur que ça ruine les performances :-/

  6. #6
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Ce n'est qu'un warning, tu peux passer outre. Tu l'aurais lancer depuis SQL*Plus (où les warnings ne sont pas activés par défaut), tu n'aurais rien vu

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    Oui je crois que je vais finir par me résigner
    Mais je t'avoue que j'aurais bien aimé comprendre pourquoi ce warning est lancé lors d'un appel à TO_DATE à l'intérieur d'un insert...

    Autant je comprends à l'intérieur d'un WHERE, autant là je me dis que soit c'est un petit bug du compilateur, soit je passe à coté de quelque chose. Et comme c'est une procédure stockée que j'essaye d'optimiser au maximum...

    Bref si jamais quelqu'un a un éclair de génie, qu'il n'hésite pas à apporter son grain de sel, en tous cas merci plaineR!

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    500
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 500
    Points : 639
    Points
    639
    Par défaut
    Je suis tout à fait d'accord sur le fait qu'il faut faire un TO_DATE(TO_CHAR(...)). Faut être carré.
    Par contre, faut être carré jusqu'au bout : ça ne changera peut-être rien, mais vous ne spécifiez pas le format du TO_DATE. Moi je ferais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    INSERT INTO tab1(mydate)
        VALUES (TO_DATE(TO_CHAR('20080101', 'YYYYMMDD'), 'YYYYMMDD'));

  9. #9
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Citation Envoyé par dgi77 Voir le message
    Par contre, faut être carré jusqu'au bout : ça ne changera peut-être rien, mais vous ne spécifiez pas le format du TO_DATE.
    Pas d'accord, ce n'est pas le format du to_date qu'on ne précise pas mais celui du to_char car 20080101 est un nombre (cf. 1è post), donc pas de format date sur un nombre.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    500
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 500
    Points : 639
    Points
    639
    Par défaut
    Effectivement... je me suis enflammé...
    Ben, je sais pas d'où ça peut venir alors...

Discussions similaires

  1. Erreur de syntaxe lors de la conversion d'une valeur datetime
    Par info3licen dans le forum Débuter avec Java
    Réponses: 10
    Dernier message: 28/05/2011, 02h31
  2. Problème lors de l'importation d'une date dans un fichier
    Par juju05 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 01/01/2010, 16h42
  3. [Free Pascal] Erreur exitcode 217 lors de la conversion d'une image en tableau
    Par _Hope_ dans le forum Free Pascal
    Réponses: 7
    Dernier message: 18/05/2009, 21h54
  4. Problème transparence lors de la conversion d'une image
    Par Riki dans le forum Général Dotnet
    Réponses: 1
    Dernier message: 20/11/2007, 13h33
  5. Erreur lors de la conversion d'une requête SELECT en DELETE
    Par SamLeChiseuji dans le forum Requêtes et SQL.
    Réponses: 9
    Dernier message: 11/07/2007, 16h09

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