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 :

"insert into table select from where" avec conditions where vides


Sujet :

PL/SQL Oracle

  1. #1
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut "insert into table select from where" avec conditions where vides
    Bonjour,
    Je cherche à faire un "select into" dans une table qui fonctionne bien sauf quand la condition where ne retourne rien. Au lieu de ne juste rien inséré, une exception est levée... Y a-t-il moyen de modifier ce comportement s'il vous plaît ?
    Merci

    EDIT : Pour compléter un peu mon besoin, je précise que je suis dans une procédure stockée où je dois effectuer une trentaine d'insertions d'affilé, indépendants les uns des autres. Si mon premier select into retourne vide, ce n'est pas une erreur, ça veut juste dire que je ne dois rien insérer dans cette table. Je veux donc passer à l'insertion via select into suivant, etc. Si je gère une exception no_data_found à la fin de ma procédure, comment est-ce que je peux lui dire de juste revenir exécuter le code suivant ? A moins d'utiliser des goto...

  2. #2
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Le sujet concerne plutôt du PL/SQL que du SQL
    Sinon pour vous aider au mieux il faudrait que nous ayons le code sous les yeux.

    Comment sont enchaîner les insert ?
    Via un curseur ?

    Il est possible d'éviter de lever une exception en utilisant un MAX par exemple, dans ce cas si aucune donnée n'est trouvée alors le résultat sera NULL.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    select noemp
    from employe
    where noemp=-1;
    
    aucune ligne sélectionnée
    
    
    select MAX(noemp)
    from employe
    where noemp=-1;
    
    MAX(noemp)
    --------------

    Mais cela reste du "bricolage" il est bien plus conseillé de gérer ces cas avec... les exceptions.

  3. #3
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Effectivement, si un admin peut bouger ce thread en PL/SQL si c'est plus approprié, pas de problème bien sûr.
    Voici le squelette de ma procédure pour plus de clarté :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    CREATE OR REPLACE PROCEDURE DOUPDATES
    (
      VAL1 IN VARCHAR2
    , res out number
    , errorText out varchar2) as
    err exception;
    begin
     
    --start transaction;
    res := 0;
    errorText := '';
     
    if VAL1 is null then
    	res := -1;
    	errorText := 'val1 is mandatory';
    	raise err;
    end if;
     
    --firstInsert
    insert into table1 (...)
    select ...
    from table1
    where ...;
     
    --secondInsert
    insert into table2 (...)
    select ...
    from table2
    where ...;
     
    --thirdInsert
    insert into table3 (...)
    select ...
    from table3
    where ...;
     
    ...
     
    dbms_output.put_line('WENT FINE');
     
    commit;
     
    Exception
       when err then
          dbms_output.put_line('WENT WRONG');
          rollback;
       when others then
          dbms_output.put_line('WENT WRONG');
          res := SQLCODE;
          errorText := SUBSTR(SQLERRM, 1, 100);
    	  rollback;
     
    null;
    END DOUPDATES;
    Si firstInsert n'insert rien, ce n'est pas une erreur, je dois juste passer à secondInsert puis à thirdInsert etc...
    Sinon j'imagine bien qu'il y a la possibilité de faire un count(*) de ma requête avant chaque insert pour valider si je fais le insert into, mais je trouve ça très lourd...
    Où alors il y a la possibilité suivante avec des GOTO aussi j'imagine qui serait intermédiaire :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    CREATE OR REPLACE PROCEDURE DOUPDATES
    (
      VAL1 IN VARCHAR2
    , res out number
    , errorText out varchar2) as
    lbGOTO varchar2(30) := 0;
    err exception;
    begin
     
    --start transaction;
    res := 0;
    errorText := '';
     
    if VAL1 is null then
    	res := -1;
    	errorText := 'val1 is mandatory';
    	raise err;
    end if;
     
    lbGOTO := 'second';
    <<firstInsert>>
    insert into table1 (...)
    select ...
    from table1
    where ...;
     
    lbGOTO := 'third';
    <<secondInsert>>
    insert into table2 (...)
    select ...
    from table2
    where ...;
     
    lbGOTO := 'fourth';
    <<thirdInsert>>
    insert into table3 (...)
    select ...
    from table3
    where ...;
     
    lbGOTO := 'fifth';
    <<fourthInsert>>
    ...
     
    dbms_output.put_line('WENT FINE');
     
    commit;
     
    Exception
       when no_data_found then
    	  if lbGOTO = 'second' then
    		GOTO secondInsert
    	  else if lbGOTO = 'third' then
    		GOTO thirdInsert
    	  else if lbGOTO = 'fourth' then
    		GOTO fifthInsert
    	  end if;
       when err then
          dbms_output.put_line('WENT WRONG');
          rollback;
       when others then
          dbms_output.put_line('WENT WRONG');
          res := SQLCODE;
          errorText := SUBSTR(SQLERRM, 1, 100);
    	  rollback;
     
    null;
    END DOUPDATES;
    EDIT : J'ai vu que je pourrais aussi imbriquer des block begin/end apparemment avec un traitement exception dans chaque mais vu le nombre d'insertions que je dois gérer, ce serait illisible. Possibilité de désactiver la levée de l'exception no_data_found peut-être ?

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Vous confondez insert into ... select... qui ne génère pas d'exception quand aucune ligne n'est insérée et select into qui génère NO_DATA_FOUND si pas de données renvoyées.

    Votre 1er bloc de code exemple fonctionne donc à priori comme vous le souhaitez.

    Par ailleurs, il est préférable de renvoyer une exception plutôt qu'un code erreur.
    Donc raise_application_error pour les exceptions personalisées et ne pas catcher when others, un code erreur pouvant facilement être ignoré.

    Mais parfois la gestion en code erreur est considérée comme le standard de développement dans certaines entreprises.

  5. #5
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Merci skuatamad,
    Effectivement, je me suis embrouillé et j'ai donc pu avoir le bon fonctionnement tel que je l'espérais.

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

Discussions similaires

  1. Problème avec condition WHERE dans commande SELECT
    Par Badouba76 dans le forum Objective-C
    Réponses: 3
    Dernier message: 08/11/2013, 18h19
  2. [MySQL] select 4 table avec Join et where un soucis
    Par Mortillus dans le forum PHP & Base de données
    Réponses: 32
    Dernier message: 03/03/2010, 11h14
  3. [ZF 1.9] [Débutant] SELECT avec condition WHERE + précisions
    Par Ibuprofène dans le forum Zend_Db
    Réponses: 5
    Dernier message: 02/02/2010, 17h25
  4. Insert avec select sur table avec Trigger d'insertion
    Par bran_noz dans le forum Développement
    Réponses: 5
    Dernier message: 23/12/2005, 14h38
  5. Sélection multi table avec condition
    Par iuz dans le forum Langage SQL
    Réponses: 8
    Dernier message: 05/05/2004, 15h04

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