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

Langage SQL Discussion :

Transformation de requête


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 16
    Points
    16
    Par défaut Transformation de requête
    Bonjour,

    J'ai une requête SQL fonctionnel, notamment sous Toad, mais qui ne compile en PRO*C.

    J'ai déjà vu ce problème et il est lié apparemment à une différence de version entre les langages SQL.

    Maintenant, étant récemment sorti de l'école et ayant une pauvre expérience du SQL, je vous avoue que je suis perdu quand on me dit de revenir à une vieille version du langage, surtout que j'ai déjà du pas mal cherché pour obtenir cette requête fonctionnelle.

    Si vous pouvez m'aider, j'en serais fortement reconnaissant. Juste me dire la technique à utiliser pour transformer la requête que voici :

    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
     
    	EXEC SQL WHENEVER SQLERROR DO OracleDBError();
     	EXEC SQL WHENEVER NOT FOUND CONTINUE;
     	EXEC SQL INSERT INTO rating_score_his 
     			(
     				person_idn,
              			rating_model,
              			model_var,
              			model_value,
              			rating_score_seq,
              			request_number,
              			last_update_user,
              			seq_num
                            )
       		SELECT person_idn,
              		rating_model,
              		model_var,
              		model_value,
              		rating_score_seq,
              		request_number,
              		last_update_user,
              		(SELECT nvl(max(seq_num), 0)+1
                 			FROM rating_score_his
                			WHERE rating_score_his.person_idn = rating_score.person_idn
                      		AND rating_score_his.rating_model = rating_score.rating_model)
        		 FROM rating_score;
    Où la partie suivante est le problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    (SELECT nvl(max(seq_num), 0)+1
                 			FROM rating_score_his
                			WHERE rating_score_his.person_idn = rating_score.person_idn
                      		AND rating_score_his.rating_model = rating_score.rating_model)
    Merci beaucoup,
    Albin Gilles.

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 016
    Points : 23 705
    Points
    23 705
    Par défaut
    Bonjour,

    Quel est le message d'erreur à la compilation ?
    Est-ce que c'est la fonction NVL qui n'est pas reconnue ?
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 16
    Points
    16
    Par défaut
    Merci de votre réponse,

    En fait il dit que le SELECT (celui qui va chercher la valeur de seq_num) est mal placé et qu'il s'attend à une valeur de la forme, voilà l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Syntax error at line 123, column 21, file DeleteRating_AGI.pc:
    Error at line 123, column 21 in file DeleteRating_AGI.pc
                            (SELECT nvl(max(seq_num), 0)+1
    ....................1
    PCC-S-02201, Encountered the symbol "nvl" when expecting one of the following:
     
       ( ) * + - / . @ | at, day, hour, minute, month, second, year,
    The symbol "(" was substituted for "nvl" to continue.
    En fait, je suis entrain de réécrire une vielle requête qui utilisait un curseur pour faire le boulot. Mais cette requête utilisait un nvl()... donc je vois pas pourquoi cela n'irait pas ici surtout que c'est accepté sous Toad..

    La réponse que l'on m'a donné sur un forum Pro*C c'est que le précompilateur ne connaît pas cette façon de faire et qu'il faut modifier ma requête notamment en utilisant du sql dynamique... mais sincérement j'ai aucune idée de ce que ça peut être..

    Merci beaucoup,
    Albin

  4. #4
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 016
    Points : 23 705
    Points
    23 705
    Par défaut
    NVL, c'est du Oracle ça, non ?
    Et en essayant de remplacer cette fonction par la fonction COALESCE (qui fait la même chose, mais qui est plus standard) ?
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    J'ai résolu mon problème de compilation mais maintenant j'ai un problème de résultat (la requête ne me retourne pas exactement ce que je veux).

    Pour faire simple, la requête doit copier le contenu de rating_score dans rating_score_his mais en ajoutant un numéro de séquence (seq_num) qui dépend de deux champs : person_idn et rating_model.

    C'est à dire que pour chaque record dans rating_score, il faut trouver le max(seq_num) dans rating_score_his pour les record ayant les même person_idn et rating_model. C'est une sorte de compteur de record ayant les même person_idn et rating_model.

    Mais il y'a un problème, parce qu'il met (par exemple) 106 au seq_num de tous les records ayant les même person_idn et rating_model que j'ajoute dans rating_score_his au lieu de 106, 107, 108,...

    La clé primaine de rating_score est person_idn, rating_model et model_var ce qui signifie qu'il est possible d'inserer plusieurs record ayant les meme person_idn et rating_model mais qu'il faut que le seq_num soit mis à jour à chaque insert.

    Est-ce qu'il est possible de faire ça en SQL pur?

    J'ai un collègue qui m'a dit que c'était parce qu'il n'y avait pas de commit après chaque insert et donc quand il faisait le select max (blabla) il ne prenait pas en compte les lignes insérées. Est-il possible de demander de commit à chaque insert ou est-ce que je prends le problème d'une mauvaise façon?

    Si le fait de commit à chaque insert dépend du SGBD j'irai demander dans le forum oracle.

    Merci beaucoup pour votre aide et votre temps,
    Albin.

  6. #6
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Au lieu d'ajouter 1 au max dans le sous-select, ajoute ROWNUM à l'extérieur du SELECT, genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT person_idn,
              		rating_model,
              		model_var,
              		model_value,
              		rating_score_seq,
              		request_number,
              		last_update_user,
              		(SELECT nvl(max(seq_num), 0)
                 			FROM rating_score_his
                			WHERE rating_score_his.person_idn = rating_score.person_idn
                      		AND rating_score_his.rating_model = rating_score.rating_model) + ROWNUM
        		 FROM rating_score;

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 16
    Points
    16
    Par défaut
    Très bonne idée malheureusement le ROWNUM n'est pas propre a person_idn/rating_model et donc les dernier lignes recoive + 890.000... mais sinon il itére bien 890.001, 890.002, 890.003, ...

    Peut-être en calculant le ROWNUM en faisant une sorte de group by person_idn/rating_model ? Mais j'avoue que je sais pas trop comment mettre ça en place..

    Merci beaucoup,
    Albin.

  8. #8
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    En fait, le mieux, c'est d'utiliser les fonctions analytiques.

    Un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT person_idn,
              		rating_model,
              		model_var,
              		model_value,
              		rating_score_seq,
              		request_number,
              		last_update_user,
              		(SELECT nvl(max(seq_num), 0)
                 			FROM rating_score_his
                			WHERE rating_score_his.person_idn = rating_score.person_idn
                      		AND rating_score_his.rating_model = rating_score.rating_model) + ROW_NUMBER() OVER(PARTITION BY rating_model, person_idn ORDER BY null)
        		 FROM rating_score;

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 16
    Points
    16
    Par défaut
    C'est parfait !

    Un grand merci je ne connaissais pas du tout ce genre de technique... Bon week-end !

    Albin

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

Discussions similaires

  1. Transformer une requête en chaîne de caractères
    Par DurDur dans le forum VBA Access
    Réponses: 1
    Dernier message: 14/03/2009, 18h40
  2. Comment transformer un requête en requête d'ajout
    Par lea022 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 17/04/2008, 18h47
  3. Transformer une requête sql dynamique
    Par ttttnht dans le forum Sybase
    Réponses: 5
    Dernier message: 24/07/2007, 07h54
  4. Transformer une requête imbriquée
    Par cans38 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 16/07/2007, 20h04
  5. Transformer ma requête
    Par juliojc13 dans le forum Requêtes et SQL.
    Réponses: 19
    Dernier message: 27/06/2007, 21h22

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