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 :

Amélioration d'un case


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Par défaut Amélioration d'un case
    Bonjour,

    J'ai un update qui utilise un case pour affecter une valeur selon une condition.

    Le case fait un select et je veux que la valeur updaté soit le résultat du select, ou 150000 si le résultat est plus grand que 150000.

    En d'autres terme je veux faire un update dont la valeur ne doit pas dépasser 150000.

    J'ai donc codé ceci (j'ai éliminé tout ce qui n'est pas nécessaire à la compréhension du problème):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    update ma_table set 
          amount = 
            case
              when (select ...) > 150000 then 150000
              else (le même select)
            end;
    Je me demandais s'il est possible de formuler ça de manière à ne pas répéter 2 fois le même select.
    Bien que j'imagine qu'oracle est assez intelligent pour ne pas exécuter le select deux fois et mettre le résultat en cache, mais comme je n'en suis pas sûr...

    Merci d'avance.

  2. #2
    Membre Expert
    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
    Par défaut
    Ton besoin est donc si ton SELECT ramène quelque chose d'inférieure à 150000 affecter cette valeur sinon une valeur Maximum

    Tu peux essayer ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    UPDATE Ma_table
    SET Ma_zone = 
        (SELECT LEAST(Valeur,150000)
        FROM
           (SELECT  Valeur
           FROM      Autre_table
           WHERE   Une_clause)
       );
    PS : A voir aussi ce que tu veux faire si la requête ramène NULL (utilisation NVL, DECODE, clause WHERE pour l'UPDATE...)

  3. #3
    Membre chevronné Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Par défaut
    Merci, je n'avais pas pensé au LEAST, c'est bien plus élégant comme ça.

    Pour le null, pour le moment je le gère avec une EXCEPTION.
    Si le select renvoie null je ne dois tout simplement pas faire l'update.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    EXCEPTION   
      when others then
        if sqlcode = -1407 then
          null;
    Mais peut-être qu'il y a plus efficace ?

  4. #4
    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
    un sous select qui ne renvoie aucune ligne ne sort pas en no_data_found, mais est égal à NULL

  5. #5
    Membre Expert
    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
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SQL> SELECT LEAST(Valeur,150000)
      2      FROM
      3         (SELECT  3200000 AS Valeur
      4         FROM      dual
      5         WHERE   1=0);
     
    aucune ligne sélectionnée
    Pas dans ce cas-ci, c'est bien un NO_DATA_FOUND qui est retourné

    Mais peut-être qu'il y a plus efficace ?
    Tout dépend ce que tu veux faire !


    EDIT : Par contre oui McM, vu que la requête est un UPDATE, tu n'auras pas de NO_DATA_FOUND mais aucune ligne de mise à jour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SQL> UPDATE t
      2  SET a = (SELECT LEAST(Valeur,150000)
      3      FROM
      4         (SELECT  3200000 AS Valeur
      5         FROM      dual
      6         WHERE   1=0));
     
    0 ligne(s) mise(s) à jour.
    Du coup, ce n'est peut-être pas le résultat que tu attends

  6. #6
    Membre chevronné Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Par défaut
    En fait comme le résultat du select est utilisé dans un update sur une colonne qui ne peut pas être null, je reçois l'erreur -1407: cannot insert null value in.
    Donc je catch cette exception comme montré dans le code plus haut.

    Ca me convient mais peut-être qu'il y a plus performant. Je sais qu'il y a un overhead quand oracle doit gérer une exception.

  7. #7
    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
    Citation Envoyé par Scriuiw Voir le message
    EDIT : Par contre oui McM, vu que la requête est un UPDATE, tu n'auras pas de NO_DATA_FOUND mais aucune ligne de mise à jour
    Pas du tout ! Un update sans clause where update toutes les lignes !

    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 TABLE T1 (a number);
     
    INSERT INTO t1 
    SELECT ROWNUM FROM all_tables WHERE ROWNUM < 5
    4 Rowsinserted
     
    COMMIT;
     
    UPDATE t1
      SET a = (SELECT LEAST(Valeur,150000)
          FROM
             (SELECT  3200000 AS Valeur
            FROM      dual
             WHERE   1=0));
     
    4 rows updated 
     
             select * from t1
    => 4 lignes vides.

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

Discussions similaires

  1. [MIGRATION] champ de type "case à cocher"
    Par The_Nail dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 10/05/2011, 11h07
  2. [VB6]rajout d'une case en haut à droite...
    Par tomnie dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 02/09/2003, 10h33
  3. Réponses: 6
    Dernier message: 26/01/2003, 13h45
  4. case sensible
    Par zdra dans le forum C++Builder
    Réponses: 2
    Dernier message: 29/11/2002, 20h15

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