decode marche pas (tour de magie) [Oracle] - SQL/NoSQL - Programmation
Marsh Posté le 04-07-2003 à 16:21:30
hop le fou a écrit : Je fais des conditions a l aide de decode dans des requetes SQL |
Tu es sur que c'est pas encore un pb de parenthèse ?
Tu voudrais pas plutot faire :
AND (('true' = decode(NVL(:NS,'0'),'0','true','false')
OR tiersct.id_ti = (select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS'))
Marsh Posté le 04-07-2003 à 16:36:52
tomlameche a écrit : |
c la meme chose
la paranthese que tu as ajouté est celle autour du test (y en a 2 maintenant ... erreur de ta part ou je louche)
NB: dans le doute g qd mem essayé mais c pareil
en fait il manque la paranthese a la fin dans le post (mais elle y est dans mon code)
donc non ce n'est pas ca...
Edit:smiley incruste...
Marsh Posté le 07-07-2003 à 12:06:39
C'est quoi l'erreur
Marsh Posté le 07-07-2003 à 12:39:13
Mara's dad a écrit : C'est quoi l'erreur |
la requete tourne dans le vide
elle ne se termine pas (alors qu'avec une valeur comme indiqué das le premier post, cela met - de 1 seconde)
elle ne marche pas que si on a donné une valeur a l'argument :NS(si c null donc l'autre argument :NC <> de NULL ca marche)
Marsh Posté le 07-07-2003 à 12:45:13
Essayes de réécrire ta requêtes avec des left join :
SELECT |
Marsh Posté le 07-07-2003 à 12:51:53
Mara's dad a écrit : Essayes de réécrire ta requêtes avec des left join :
|
je suppose que ce que tu as écris (les +) correspond a ce que g écris (je connais pas) mais tout cela est conditionnel et je ne sais pas si ca ne va pas poser de probleme
je vais essayer
je répond apres
merci
Marsh Posté le 07-07-2003 à 12:54:48
En fait, le left join , je pense pas que ce soit la solution de ton problème !
En revanche, pourquoi réinventer la roue :
'true' = decode(NVL(:NS,'0'),'0','true','false') |
et équivalent à :
:NS IS NULL |
Donc ton code devient :
AND |
Celà dit, y'a certainement moyen de virer la sous-requête pour tout faire en une seule...
Tu peux nous montrer la requête complète ?
Marsh Posté le 07-07-2003 à 13:53:56
Mara's dad a écrit : En fait, le left join , je pense pas que ce soit la solution de ton problème !
|
en fait le decode je l'utilise pour faire des condition (faire des comparaisons que si g une valeur :
http://forum.hardware.fr/forum2.ph [...] subcat=395
je ne sais pas si le is Null fonctionne mais je vais essayer
par contre oracle ne connait pas les (+) et me dit qu il reconnait plus la colonne...
voila la requete complete:
select contrat.numcont_ct NUMCONT,
produit.refer_pr REFPROD,
contrat.prann_ct PRANN,
decode(mvt.cdpos_mvt,1,'En Cours',2,'Mis en Demeure',3,'Suspendu',4,'Résilié','Autre') POSITION
from entcontrat,contrat,tiersct,produit,ssmvt,mvt
where contrat.id_ct = tiersct.id_ct
and contrat.numali_ct = 0
and contrat.id_ect = entcontrat.id_ect
and contrat.cd_smv = ssmvt.cd_smv
and ssmvt.cd_mvt = mvt.cd_mvt
and contrat.cd_pr = produit.cd_pr
and tiersct.cd_tt = 'SO'
and numavt_ct = (select max(numavt_ct)
from contrat
where id_ect = entcontrat.id_ect
and dtef_ct <= to_date(:DS,'DDMMYYYY')
and dtcrec_ct <= to_date(:DS,'DDMMYYYY')
)
and nummvt_ct = (select max(c.nummvt_ct)
from contrat c
where c.id_ect = entcontrat.id_ect
and contrat.numavt_ct = c.numavt_ct
and c.dtef_ct <= to_date(:DS,'DDMMYYYY')
and dtcrec_ct <= to_date(:DS,'DDMMYYYY')
)
and contrat.numcont_ct = NVL(:NC,contrat.numcont_ct)
and ('true' = decode(NVL(:NS,'0'),'0','true','false') OR tiersct.id_ti = (select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS'))
Marsh Posté le 07-07-2003 à 14:30:45
Mara's dad a écrit : En fait, le left join , je pense pas que ce soit la solution de ton problème !
|
En effet IS NULL marche très bien
ca m etonnerai que ca avance plus vite mais en tout cas ca fai bcp plus propre...
Marsh Posté le 07-07-2003 à 15:38:54
Heu, t'est certain d'être obligé de tout faire en une seule requête.
T'as quand même un paquet de cas différent en fonction de :NS, :NC et S
Je suppose que si tu as :NC, tu n'as ni S, ni :NS
par exemple :
:NC pas NULL -> S est NULL et :NS est NULL
:NC NULL -> S peut être NULL et :NS peut être NULL
Si c'est un truc du genre, il doit y avoir mayen de faire des requêtes plus optimisées en fonction des cas.
Marsh Posté le 07-07-2003 à 16:07:39
Mara's dad a écrit : Heu, t'est certain d'être obligé de tout faire en une seule requête. |
non en fait S est obligatoire et on a soit :NC soit :NS
donc il n'y a pas bcp de cas différents (4)
en ce qui concerne la requete, en fait je dois adapter des requetes écrites dans du php (conditions faciles a réaliser donc avec des if) dans des requetes écrites dans des fichiers xsql utilisé par les feuille de style Xsl qui transforme le tout en xml et en html
g donc juste essayé de conserver la structure de la requete de base
et justement c donc un probleme paske je sais pas comment décomposer les requetes avec ca (possible?)
je ne pe rien imbriquer au milieu de mes requetes et je n'arrive meme pas a réutiliser le résultat dans de nouvelles requetes (mais ca doit etre possible mais je cherche...)
je peux aussi utiliser les foncitons Xpath sur mon fichier xml obtenu mais ca m'étonnerai que ce soit aussi rapide que le moteur de Oracle
donc je galere...
Marsh Posté le 07-07-2003 à 16:36:25
Bon, alors, qu'est ce que tu pense de çà :
AND tiersct.id_ti = decode( :NS, NULL, tiersct.id_ti, ( select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS' ) ) |
à la place de
AND ('true' = decode(NVL(:NS,'0'),'0','true','false') |
Marsh Posté le 07-07-2003 à 16:44:15
Mara's dad a écrit : Bon, alors, qu'est ce que tu pense de çà :
|
en effet ca fonctionne
c bizzare je croyais avoir deja essayé de faire ce truc et qu il m'avait refoulé...
j avais pas du ecrire ca comme y fo
merci
Marsh Posté le 07-07-2003 à 17:36:58
Ok, content pour toi que çà marche !
Mais quand même, du point de vue perfs, çà doit être la cata ton truc non ?
Marsh Posté le 07-07-2003 à 17:44:38
Mara's dad a écrit : Ok, content pour toi que çà marche ! |
etrangement il n y a pas de différences visible entre les 2 types de requetes...
je sais pas pkoi
c bizzare en plus pask il y a effectivement plus de test dans les requetes en 1 bloc
g cherché d'autres alternatives (comme avec les fonctions Xpath) mais soit c plus long, soit g pas trouvé...
donc a défaut...
cette solution a été choisi paske elle permet l'exportation des résultats des requetes sous n'importe quelle forme (xml-> excel,pdf...) ce qui est bien pratique pour les utilisateurs
Marsh Posté le 09-07-2003 à 15:10:47
Bon je suis lourd mais g un vrai probleme avec les decode
soit g rien compris, soit ceux qui ont écris Oracle sont la confrérie amicale des magiciens
ceci fonctionne (normal):
where (:NC IS NULL OR :NC = numcont_ct) |
ceci fonctionne (non g pas plus simple):
numcont_ct IN |
mais ceci ne fonctionne pas :
(:NS IS NULL OR (numcont_ct IN |
ceci non plus d'ailleur (n'importe quoi...)
Code :
|
hop magie? qqun a compri?
*Remarque* : C'est évidemment la partie longue de la requete car quand :NS est NULL la requete est tres rapide
par contre l'inverse...
Marsh Posté le 09-07-2003 à 16:03:41
Rectification : ca fonctionne mais c extremement lent
cad que au lieu de mettre 3 ou 4 secondes, ca met environ 3 ou 4 minutes
je pensais que ca marchait pas paske j avais pas attendu jusque la
mais ca n arrange en rien mon pb car je ne pe pas attendre 10 jours avant d avoir une reponse a cette requete...
une idée pour remplacer ou pour corriger ca?
Marsh Posté le 09-07-2003 à 16:06:05
Et ça ?
(:NS IS NULL OR (:NS IS NOT NULL and (numcont_ct IN
(select distinct (contrat.numcont_ct)
from contrat,tiersct
where contrat.id_ct = tiersct.id_ct
AND tiersct.id_ti = (select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS')
AND contrat.numali_ct = 0))))
Marsh Posté le 09-07-2003 à 16:10:25
vttman2 a écrit : Et ça ? |
hum c quoi la différence?
ca risque juste d'allourdir le code non?
bon je vais essayer...
Edit: non ca n'arrange rien du tout mais le contraire m'aurait étonné...
Marsh Posté le 09-07-2003 à 16:25:55
Ouhais moi aussi ...
A la reflexion j'aurais mieux fait
de rien poster sur ce coup-là
Marsh Posté le 09-07-2003 à 16:41:09
Mara's dad a écrit : Bon, alors, qu'est ce que tu pense de çà :
|
Revenons à la partie qui marchait pas,
tant que j'y suis ...
AND tiersct.id_ti = decode( :NS, NULL, tiersct.id_ti, ( select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS' )
<=>
si :NS est NULL alors ma condition à rajouter dans le Where
est AND tiersct.id_ti = tiersct.id_ti
Sinon c AND tiersct.id_ti = ( select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS' )
alors que
AND ('true' = decode(NVL(:NS,'0'),'0','true','false')
OR tiersct.id_ti = (select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS'))
<=>
AND ('true' = decode(NVL(:NS,'0'),'0','true','false')
OR tiersct.id_ti = ????
Comment évaluer ce résultat sachant que ta
requête (select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS') va renvoyer :
Rien
1 enr.
Plusieurs enr.
Moi j'aurais tester avec un EXIST ou NOT EXIST
Bon si j'ai dit une connerie ...
ça en fera 2 dans ce topic
Marsh Posté le 09-07-2003 à 16:52:34
vttman2 a écrit : |
alors pour la premiere partie je suis d accord
pour la seconde partie je suis d accord (pas contraignant pour 2 sous... )
par contre pour la suite non
ce que je fais c de la modification de requete
ce qui a déja été mis en place (pas par moi) fonctionne
le truc c que je dois executer des morceaux de requetes et d'autres non (d ou lutilisation abusive de decode ou is null partout) étant donné que ces requetes étaient utilisées auparavant dans du langage php (qui permet donc les tests bien plus facilement)
donc en gros non ca ne me sert rien d'utiliser Exist ou Not Exist
bien essayé...
Marsh Posté le 09-07-2003 à 16:54:15
vttman2 a écrit : |
allez une 1,5 et on n'en parle plus
Marsh Posté le 10-07-2003 à 17:22:19
Le problème, je pense, c'est que quand tu fais :
Expression 1 OR expression 2 |
Dans ce cas, il me semble qu'Oracle n'est pas capable de ne pas évaluer l'expression 2.
Donc dans :
( |
(Oui je sais çà prends de la place ! Mais j'arrive pas à lire sinon...)
Bon en fait, dans ce cas, il évalue tout le temps la deuxième expression et çà doit le faire ramer à mort !
Alors que si tu le fait avec le décode, ben c'est explicite
AND tiersct.id_ti = decode( :NS, NULL, tiersct.id_ti, ( select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS' ) ) |
L'expression "select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS'" n'est pas évaluée si :NS est NULL !
En fait, Evaluer systématiquement les deux expressions (pour un OR ou un AND) s'explique.
Si je fait un truc du genre :
myFunction( 'toto' ) OR myFunction( 'titi' ) |
Il se peut très bien que MyFunction fasse des choses très importantes.
Il est possible que je souhaite que myFunction( 'titi' ) soit exécuté même si myFunction( 'toto' ) est vrai.
Tu sais donc ce qui te reste à faire
Marsh Posté le 11-07-2003 à 09:11:35
ben en fait non
la 2eme expression est assez rapide puisque seule, elle met 2 ou 3 secondes (oui c long mais c normal...)
donc je pense que meme si la 2eme expression etait évalué (correctement) ca ne prendrait pas autant de tps que ca le fait
pour ce qui concerne si la 2eme expression est évaluée ou non, je ne sais pas mais je ne crois pas car lorsque je fais des tests dans celle ci dans mon select, elle n'est pas prise e compte...
alors peut etre qu elle evalué et pas prise en compte mais ca je ne sais pas...
peut etre que je devrais faire un decode mais il me semble que ca m avait posé un pb...
je vais reessayer...
merci
Marsh Posté le 11-07-2003 à 10:14:55
J'ai fait des essais, et j'ai des résultats trè louches !
select 'toto' from dual where test_func( 'OUI' ) = 1 or test_func( 'Non' ) = 1;
Ma fonction test_func fait un dbms_output.put_line( b );
Et ben la première fois que j'exécute la requête, j'ai 4 appels à ma fonction, 2 pour chaque valeurs, et ensuite, li ne l'appelle que pour 'OUI'.
Donc en fait il appelle les fonctions un peut quand il veut
Dans une requête un peu complexe, je ne serait pas étonné qu'il boucle à chaque fois.
Citation : la 2eme expression est assez rapide puisque seule, elle met 2 ou 3 secondes |
Ok, 2 ou 3 secondes, mais si :NS est null, il l'execute combien de fois ?
Marsh Posté le 11-07-2003 à 10:22:20
Mara's dad a écrit : J'ai fait des essais, et j'ai des résultats trè louches !
|
m enfin
c du n importe quoi ca?!?!?
alors en effet il faut que j utilise du decode partout...
c ennuyeux quand meme paske c pas toujours possible
je vais essayer d arranger ca...
en tout cas merci
et vive Oracle...
Marsh Posté le 04-07-2003 à 14:33:24
Edit:le probleme actuel est a la fin
Je fais des conditions a l aide de decode dans des requetes SQL
Je ne comprend pas pkoi ceci ne marche pas...
AND ('true' = decode(NVL(:NS,'0'),'0','true','false')
OR tiersct.id_ti = (select id_ti from tiers where num_ti = :NS AND cd_tt = 'AS'))
ceci ne pose pas de pb quand je n'ai pas donné de valeur a mon parametre (:NS = NULL)
par contre si :NS a une valeur ben ca marche pas
alors que ceci marche tres bien:
and tiersct.id_ti = (select id_ti from tiers where num_ti = 01089181 AND cd_tt = 'AS')
qqun a une idée de ce que c l'erreur
Edit : oui il manquait une paranthese a la fin dans ce post
Message édité par hop le fou le 09-07-2003 à 15:11:55