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 :

Clause Where avec variable en erreur


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Chargé de projets
    Inscrit en
    Février 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chargé de projets

    Informations forums :
    Inscription : Février 2017
    Messages : 3
    Par défaut Clause Where avec variable en erreur
    Bonjour à tous,

    j'aurais besoin d'un peu d'aide sur une requête Oracle ou je voudrais utiliser des variables afin de rendre plus visible et facile d'accès la recherche de données. Le résultat de la requête doit être affiché sur un écran et il y aura donc plusieurs éléments résultants de celle-ci
    J'ai la requête ci-dessous qui fonctionne parfaitement. Or, je souhaiterais remplacer le sysdate, par une date que je pourrais déclarer en début de requête
    J'ai tenté d'utiliser les variables mais la requête retourne plusieurs éléments. J'ai tenté d'utiliser la fonction cursor mais j'ai du mal à aller jusqu'au bout, et surtout afficher le résultat de ma requête sur Toad.

    Voici la requête qui fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select mr.code, mr.creationdate
    from cswo_mr mr
    left join cswo_mrstatus mrs on mr.id=mrs.origin_id 
    where to_char(mr.creationdate,'yyyy-mm-dd HH24:mi:ss') between to_char(sysdate,'yyyy-mm-dd') ||' 05:00:00' and to_char(sysdate,'yyyy-mm-dd') ||' 12:59:59'
    Voici le système que j'aimerais mettre en place mais qui ne marche pas :
    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
    Declare 
    DateDeb DATE;
    DateFin DATE;
    HeureDeb varchar2(30);
    HeureFin varchar2(30);
    di varchar2(33);
     
    Begin 
    DateDeb:=to_date('2016-01-01','yyyy-mm-dd');
    DateFin:=to_date('2017-01-31','yyyy-mm-dd');
    HeureDeb:=' 05:00:00';
    HeureFin:=' 12:59:59';
        select mr.code into di
        from cswo_mr mr
        left join cswo_mrstatus mrs on mr.id=mrs.origin_id 
        where mr.creationdate between DateDeb || HeureDeb  and  datefin || HeureFin;
    End;
    /
    J'ai le message d'erreur ci-dessous .
    ORA-01422: l'extraction exacte ramène plus que le nombre de lignes demandé
    ORA-06512: à ligne 14
    Un peu d'aide serait nécessaire svp. Merci

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 599
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Le message d'erreur est explicite : la requête sélectionne plus d'une seule ligne, or, une requête hors curseur ne peut concerner qu'une seule ligne

    Cela signifie que la requête que vous formatez ne produit pas exactement le même filtre que celle qui fonctionne ou bien que le contenu de la base de données a évolué

    Comme la requete qui fonctionne se base sur SYSDATE, et celle qui ne fonctionne pas sur une plage de dates allant du 01-01-2016 au 31-01-2017, la réponse est toute trouvée

    De plus, la façon dont vous construisez vos valeurs de début et de fin de plage rend la requête non sargable, ce qui signifie que même si un index existe pour les critères de date, il ne pourra pas être utilisé, attention aux perfs donc

  3. #3
    Candidat au Club
    Homme Profil pro
    Chargé de projets
    Inscrit en
    Février 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chargé de projets

    Informations forums :
    Inscription : Février 2017
    Messages : 3
    Par défaut
    Merci pour votre réponse, en parcourant les divers tuto, j'avais vu qu'il fallait utiliser les cursors mais je n'arrive pas à saisir les syntaxes correctes et surtout comment obtenir la même chose qu'un select. J'ai bien testé la requête ci-dessous mais je bute ensuite pour savoir quoi faire de mon cursor. Comment afficher tous les éléments créés entre les 2 dates que j'ai précisé, ce qui d'après ce que j'ai compris est "stocké" dans le cursor?

    Concernant la différence entre la requête qui fonctionne et celle qui ne fonctionne pas, au début j'utilise sysdate pour définir l'intervalle mais le sysdate sera au final stocké dans mes variable. Du coup, le fait que ça ne fonctionne pas, pour moi ne vient pas des données mais de ce que je défini. Désolé si ce n'est pas clair mais je débute dans l'utilisation de variables et malgré les tutos, je bute



    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
    Declare 
    DateDeb DATE;
    DateFin DATE;
    HeureDeb varchar2(30);
    HeureFin varchar2(30);
    di varchar2(33);
    
    cursor tst is 
        select mr.code into di
        from cswo_mr mr
        left join cswo_mrstatus mrs on mr.id=mrs.origin_id 
        where mr.creationdate between DateDeb || HeureDeb  and  datefin || HeureFin;
    
    Begin 
    DateDeb:=to_date('2016-01-01','yyyy-mm-dd');
    DateFin:=to_date('2017-01-31','yyyy-mm-dd');
    HeureDeb:=' 05:00:00';
    HeureFin:=' 12:59:59';
    
    open tst ;
    
    end;

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 599
    Billets dans le blog
    10
    Par défaut
    Si vous avez des doutes sur l'affectation de vos variables, affichez en le contenu avant exécution de la requete

    Pour l'utilisation d'un curseur, il faut
    - le déclarer (CURSOR TOTO IS ...
    - l'ouvrir (OPEN)
    - le parcourir (FETCH)
    - le fermer (CLOSE)

    vous n'avez fait que les 2 1ères étapes

    Une remarque : le curseur ne s'impose que s'il est normal fonctionnellement de traiter plusieurs lignes, si au contraire il ne faut qu'une seule ligne, alors la bonne démarche est soit d'affiner le filtrage pour avoir un critère unique, soit d'ajouter une clause permettant de ne traiter qu'une seule des lignes. Un curseur sera toujours moins performant qu'un select direct, c'est pourquoi il ne faut l'utiliser que si c'est fonctionnellement requis.

  5. #5
    Candidat au Club
    Homme Profil pro
    Chargé de projets
    Inscrit en
    Février 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chargé de projets

    Informations forums :
    Inscription : Février 2017
    Messages : 3
    Par défaut
    Voici ci-dessous la requête avec le fetch mais toujours rien. Je n'ai plus d'erreur mais je n'ai rien en sortie, pourtant, à la place d'utiliser mes variables, j'ai sélectionné "en dur" un élément (code='DI082074') pour être sur d'avoir des données à afficher.

    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
    Declare 
    DateDeb DATE;
    DateFin DATE;
    HeureDeb varchar2(30);
    HeureFin varchar2(30);
     
    cursor c1 is 
        select *
        from cswo_mr mr
        left join cswo_mrstatus mrs on mr.id=mrs.origin_id 
        where code='DI082074'/*mr.creationdate between DateDeb || HeureDeb  and  datefin || HeureFin*/;
    dt c1%ROWTYPE; 
     
    Begin 
    DateDeb:=to_date('2016-01-01','yyyy-mm-dd');
    DateFin:=to_date('2017-01-31','yyyy-mm-dd');
    HeureDeb:=' 05:00:00';
    HeureFin:=' 12:59:59';
     
    open c1 ;
        loop
            fetch c1 into dt ;
            EXIT WHEN c1%NOTFOUND;
            DBMS_OUTPUT.PUT_LINE( dt.code );
        end loop;
    close c1 ;
    end;
    /

    Mes données sont contenues dans la table cswo_mr

    Pour rappel, je veux afficher en résultat tous les éléments qui ont été créés entre 2 dates, à savoir les variables. Comme j'aurais utilisé un select classique

    Merci d'avance

Discussions similaires

  1. requete SQL clause WHERE avec variable
    Par gabule dans le forum JDBC
    Réponses: 6
    Dernier message: 09/01/2019, 11h04
  2. Problème de variable dans la clause WHERE avec CONVERT + DATE
    Par Archi89 dans le forum Développement
    Réponses: 4
    Dernier message: 09/01/2015, 20h35
  3. [MySQL] Creer une clause WHERE avec deux conditions donne erreur
    Par Salsaboy60 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 15/04/2014, 10h39
  4. la clause where avec une variable
    Par jessjess dans le forum Requêtes
    Réponses: 1
    Dernier message: 14/11/2011, 08h53
  5. Variable d'une clause where avec quote
    Par kcizth dans le forum Langage SQL
    Réponses: 1
    Dernier message: 17/04/2008, 15h43

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