Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/11/2011, 13h04   #1
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 25
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2011
Messages : 25
Points : 7
Points : 7
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 :
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 :
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.
AlbinOSG est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 13h15   #2
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 426
Points : 6 426
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
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 13h31   #3
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 25
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2011
Messages : 25
Points : 7
Points : 7
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 :
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
AlbinOSG est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2011, 13h37   #4
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 426
Points : 6 426
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
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 08h47   #5
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 25
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2011
Messages : 25
Points : 7
Points : 7
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.
AlbinOSG est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 10h52   #6
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
Salut !

Au lieu d'ajouter 1 au max dans le sous-select, ajoute ROWNUM à l'extérieur du SELECT, genre :
Code :
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/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 11h42   #7
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 25
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2011
Messages : 25
Points : 7
Points : 7
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.
AlbinOSG est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 12h17   #8
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
En fait, le mieux, c'est d'utiliser les fonctions analytiques.

Un truc du genre
Code :
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/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 13h21   #9
Invité régulier
 
Homme
Inscription : novembre 2011
Messages : 25
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : novembre 2011
Messages : 25
Points : 7
Points : 7
C'est parfait !

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

Albin
AlbinOSG est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h40.


 
 
 
 
Partenaires

Hébergement Web