requtete pas facile [SQL] - SQL/NoSQL - Programmation
Marsh Posté le 26-06-2003 à 14:24:37
Simple comme choux
where mon_attribut = decode(la_valeur_renvoyee_par_le_formulaire, 5, 4, la_valeur_renvoyee_par_le_formulaire ) and nouveau_champ = decode(la_valeur_renvoyee_par_le_formulaire, 5, nouvelle_condition, nouveau_champ)
Marsh Posté le 26-06-2003 à 14:53:54
MagicBuzz a écrit : Simple comme choux |
la premiere partie de cette solution correspond a mon REPLACE
la 2eme partie est un peu plus tordu mais je crois l'avoir compri
le pb c que je n'ai pas un =, j'ai un IN et donc j'ai un ensemble de valeur comme nouvelle condition et ca a pas l'air de plaire à Oracle...
...
AND mvt.cdpos_mvt = decode(: PFP, 5, 4, : PFP)
AND contrat.cd_smv in (decode(: PFP, 5, ('RESILIMP','RESILMED','RSLCNPT'), contrat.cd_smv))
comment faire?
(g mis un espace au milieu de : et PFP pour pas avoir FP
Marsh Posté le 26-06-2003 à 14:56:30
MagicBuzz a écrit : Simple comme choux |
et puis il y a un autre pb
étant donné qu on remplace la valeur 5 par la valeur 4, on ne la retrouvera jamais donc on ne fera jamais la condition
on peut passer la condition avant mais le probleme est le meme à moins d'utiliser une autre variable (que celle envoyée par le formulaire) non?
Marsh Posté le 26-06-2003 à 15:11:22
hop le fou a écrit : |
est ce que cette monstruosité est autorisée?
mvt.cdpos_mvt = decode(: PFP,5,4 AND contrat.cd_smv in ('RESILIMP','RESILMED','RSLCNPT'), : PFP)
parce que ca devrait marché...
Marsh Posté le 26-06-2003 à 15:56:43
ReplyMarsh Posté le 26-06-2003 à 16:06:26
Pour le coup du IN, t'es malheureusement baisé.
J'ai à la limite un début de piste en tête, mais ça va prendre trop de temps à expliquer maintenant, relance-moi ce soir, et si j'ai pas oublié, je t'explique.
Sinon, pour le coup du 5 remplacé par 4, je vois pas où est le problème.
Pour info, un DECODE ça marche comme ça :
DECODE(A, B, C, D, E, F)
Revient à :
Switch (A)
{
Case B:
return C;
Case D:
return E;
default:
return F
}
PS: DECODE prends autant de paramètre que tu veux, le minimum étant 3.
Si le dernier paramètre est omis (nombre impair de paramètres passés) alors la valeur par défaut sera la valeur qui est en entrée (premier paramètre).
Donc ça ne fait pas un replace, y'a toute une interprétation conditionnelle derrière.
Marsh Posté le 26-06-2003 à 16:08:57
Bon, rapidement, pour le coup du IN, la solution à laquelle je pense (bidouille MagicBuzzienne powa )
where field = champ and (true = decode(la_valeur_renvoyee_par_le_formulaire, 5, true, false) AND toto in (la_liste))
T'ain ça se vois pas du tout que je passe mes journée à faire des requêtes à la con moi
Marsh Posté le 26-06-2003 à 16:11:35
MagicBuzz a écrit : Pour le coup du IN, t'es malheureusement baisé. |
ben c ma doc qui est pourrie alors c t indiqué que ca faisait un remplacement...
http://www.laltruiste.com/document [...] haine.html bourde+2
OK pour le case je ferai un up plus tard
Marsh Posté le 26-06-2003 à 16:19:46
Bah la doc est en effet pourrie.
Ca fait un replace conditionnel.
Par exemple :
select ltrim(decode(personne.titre, 'M', 'Monsieur ', 'Mme', 'Madame ', 'Mrg', 'Monseigneur ', 'Dr', 'Docteur ', 'P', 'Professeur ', ' ') || personne.nom) as Contact
from personne
=> Ca te "decode" l'abréviation de la civilité en la civilité entière.
Un autre exemple :
select entite.id, decode(entite.type, 'news', select news.titre where news.id = entite.id, 'article', select article.titre where article.id = entite.id, 'Non trouvé') from entite
=> Ca te retourne la liste de toutes les entités, avec leur titre retrouvé dans la table correspondant au type de l'entité. Pour les entité non trouvées, ça arriche un message d'erreur.
En somme, DECODE est assez complexe au permier abords, mais c'est MONSTRUEUSEMENT puissant quand tu sais t'en servir.
En gros : dès qu'une requête semble impossible, c'est qu'un petit decode de derrière les fagots sera nécessaire (en éxagérant un peu )
Marsh Posté le 26-06-2003 à 16:27:01
MagicBuzz a écrit : Bah la doc est en effet pourrie. |
mais donc ca ne fera pas un replace au meme titre que REPLACE qui lui écrase la valeur de ma variable...
g essayé le truc que tu ma dit (mais j y ai rien compris...) mais ca ne marche que si la valeur de ma variable = 4
Marsh Posté le 26-06-2003 à 16:31:33
lequel ?
poste la requête qui merde, c'est plus facile quand on sait exactement de quoi on parle
Marsh Posté le 26-06-2003 à 16:36:16
MagicBuzz a écrit : lequel ? |
voila la requete entiere
select contrat.numcont_ct NUMCONT,
produit.refer_pr REFPROD,
tiers.desig1_ti||' '||tiers.desig2_ti ASSURE,
contrat.prann_ct PRANN,
contrat.cd_frc FRACT,
contrat.cd_smv DERNMVT,
to_char(contrat.dtef_ct,'DD/MM/YYYY') DATEPOS,
to_char(contrat.dtech_ct,'MM') ECHCE,
adrti.adr1_adt ADRESSE,
adrti.cp_adt CP,
adrti.ville_adt VILLE
FROM apport, ctint, entcontrat, contrat, tiersct, produit, ssmvt, mvt,adrti,tiers
WHERE entcontrat.id_ect = contrat.id_ect
AND numavt_ct = (SELECT MAX (numavt_ct)
FROM contrat
WHERE id_ect = entcontrat.id_ect
AND numali_ct = 0
AND to_char(nvl(dtcrec_ct,dtmod_ct),'YYYYMMDD') <= S
AND to_char(dtef_ct,'YYYYMMDD') <= :FI
AND to_char(dtef_ct,'YYYYMMDD') >= (select REPLACE(:DP,'','10000101')FROM DUAL)
)
AND nummvt_ct = (SELECT MAX (c.nummvt_ct)
FROM contrat c
WHERE c.id_ect = entcontrat.id_ect
AND c.numali_ct = 0
AND c.numavt_ct=contrat.numavt_ct
AND to_char(nvl(c.dtcrec_ct,c.dtmod_ct),'YYYYMMDD') <= S
AND to_char(c.dtef_ct,'YYYYMMDD') <= :FI
AND to_char(dtef_ct,'YYYYMMDD') >= (select REPLACE(:DP,'','10000101')FROM DUAL)
)
AND contrat.cd_smv = ssmvt.cd_smv
AND ssmvt.cd_mvt = mvt.cd_mvt
AND mvt.cdpos_mvt = DECODE(:PFP,'5','4',:PFP)
AND (true = decode(:PFP, 5, true, false) AND toto in ('RESILIMP','RESILMED','RSLCNPT'))
AND contrat.cd_pr = produit.cd_pr
AND entcontrat.id_ect = ctint.id_ect
AND contrat.dtef_ct BETWEEN ctint.dtdeb_cin AND NVL (dtfin_cin, dtef_ct)
AND ctint.adrenv_cin = 1
AND contrat.numali_ct = 0
AND contrat.cdtype_ct <> 'P'
AND ctint.id_int = apport.id_int
AND contrat.id_ct = tiersct.id_ct
AND tiersct.cd_tt = 'AS'
AND to_char(nvl(contrat.dtcrec_ct,contrat.dtmod_ct),'YYYYMMDD') <= S
AND tiersct.id_ti = tiers.id_ti
AND tiers.id_ti = adrti.id_ti
AND adrti.princ_adt = 1
AND apport.num_int = :NI
AND contrat.cd_pr in (Select cd_pr
From produit
Where refer_pr = R OR R = 'ALL'
)
ORDER BY contrat.numcont_ct,
produit.refer_pr,
contrat.cd_smv
la partie qui déconne est celle ou il ya de l'espace autour
il va surement yavoir des smiley au milieu a cause des parametres commencant par :
je ne comprend pas comment marche le decode en mettant false et true...
Marsh Posté le 26-06-2003 à 16:42:37
Juste histoire de voir plus clair (aucune modif)
MagicBuzz a écrit : lequel ? |
voila la requete entiere
select contrat.numcont_ct NUMCONT,
produit.refer_pr REFPROD,
tiers.desig1_ti||' '||tiers.desig2_ti ASSURE,
contrat.prann_ct PRANN,
contrat.cd_frc FRACT,
contrat.cd_smv DERNMVT,
to_char(contrat.dtef_ct,'DD/MM/YYYY') DATEPOS,
to_char(contrat.dtech_ct,'MM') ECHCE,
adrti.adr1_adt ADRESSE,
adrti.cp_adt CP,
adrti.ville_adt VILLE
FROM apport, ctint, entcontrat, contrat, tiersct, produit, ssmvt, mvt,adrti,tiers
WHERE entcontrat.id_ect = contrat.id_ect
AND numavt_ct = (SELECT MAX (numavt_ct)
FROM contrat
WHERE id_ect = entcontrat.id_ect
AND numali_ct = 0
AND to_char(nvl(dtcrec_ct,dtmod_ct),'YYYYMMDD') <= S
AND to_char(dtef_ct,'YYYYMMDD') <= :FI
AND to_char(dtef_ct,'YYYYMMDD') >= (select REPLACE(:DP,'','10000101')FROM DUAL)
)
AND nummvt_ct = (SELECT MAX (c.nummvt_ct)
FROM contrat c
WHERE c.id_ect = entcontrat.id_ect
AND c.numali_ct = 0
AND c.numavt_ct=contrat.numavt_ct
AND to_char(nvl(c.dtcrec_ct,c.dtmod_ct),'YYYYMMDD') <= S
AND to_char(c.dtef_ct,'YYYYMMDD') <= :FI
AND to_char(dtef_ct,'YYYYMMDD') >= (select REPLACE(:DP,'','10000101')FROM DUAL)
)
AND contrat.cd_smv = ssmvt.cd_smv
AND ssmvt.cd_mvt = mvt.cd_mvt
AND mvt.cdpos_mvt = DECODE(:PFP,'5','4',:PFP)
AND (true = decode(:PFP, 5, true, false) AND toto in ('RESILIMP','RESILMED','RSLCNPT'))
AND contrat.cd_pr = produit.cd_pr
AND entcontrat.id_ect = ctint.id_ect
AND contrat.dtef_ct BETWEEN ctint.dtdeb_cin AND NVL (dtfin_cin, dtef_ct)
AND ctint.adrenv_cin = 1
AND contrat.numali_ct = 0
AND contrat.cdtype_ct <> 'P'
AND ctint.id_int = apport.id_int
AND contrat.id_ct = tiersct.id_ct
AND tiersct.cd_tt = 'AS'
AND to_char(nvl(contrat.dtcrec_ct,contrat.dtmod_ct),'YYYYMMDD') <= S
AND tiersct.id_ti = tiers.id_ti
AND tiers.id_ti = adrti.id_ti
AND adrti.princ_adt = 1
AND apport.num_int = :NI
AND contrat.cd_pr in (Select cd_pr
From produit
Where refer_pr = R OR R = 'ALL'
)
ORDER BY contrat.numcont_ct,
produit.refer_pr,
contrat.cd_smv
la partie qui déconne est celle ou il ya de l'espace autour
il va surement yavoir des smiley au milieu a cause des parametres commencant par :
je ne comprend pas comment marche le decode en mettant false et true...
Marsh Posté le 26-06-2003 à 16:44:06
Argh !
Oui, je me suis planté
J'ai toujours été une bite en algèbre de bool, je fais pas assez attention
AND mvt.cdpos_mvt = DECODE(:pFP,'5','4',:pFP) |
Marsh Posté le 26-06-2003 à 16:44:47
PS: intervertis le true et false, et mis un OR à la place du AND dans la condition dans les parenthèses.
Now ça doit marcher
Marsh Posté le 26-06-2003 à 16:51:48
MagicBuzz a écrit : PS: intervertis le true et false, et mis un OR à la place du AND dans la condition dans les parenthèses. |
hélas non ca ne marche pas
meme pas avec 4
il n ya pas d erreur dans la requete mais en moins d'1 seconde elle se termine et ne renvoie rien
(alors qu il lui fo bien 4-5 secondes normalement)
en fait sans utiliser decode, j arrive a faire marcher 4 et 5 mais pas 123 (je cherche comme ca mais je trouve pas...)
Marsh Posté le 26-06-2003 à 16:58:03
Euh...
Je viens de voir un truc :
1) Un coup c'est '4' et '5' et l'autre, c'est 5.
=> Armonise, c'est source de problèmes.
2) C'est quoi ce "toto" que tu as laissé ? Faut mettre le nom du champ devant contenir les données du IN
Marsh Posté le 26-06-2003 à 17:02:04
MagicBuzz a écrit : Euh... |
oui le toto je m en suis rendu compte
c paske je deviens fou
j essaye de changer les ' depuis tout a l heure mais je sais pas si il fo en mettre ou non
dans le replace qui fonctionne, je les mis mais ca ne fonctionne pas avec ce decode...
Marsh Posté le 26-06-2003 à 17:13:35
CA A MARCHEEEEEEEEEEEEEEEEEEEEEE
c magnifique
c bo
c merveilleux
il fallait des ' partout pour pas qu il prenne ca pour des noms de colonnes...
AND mvt.cdpos_mvt = DECODE(:pFP,'5','4',:pFP)
AND ('true' = decode(:pFP,'5','false','true') OR contrat.cd_smv in ('RESILIMP','RESILMED','RSLCNPT'))
merci bcp de m'avoir aidé et d avoir été aussi patient
Marsh Posté le 26-06-2003 à 17:24:56
Bah j'ai rien à foutre là
Sinon, chuis assez patient, parceque j'aime bien me triturer la tête avec des requêtes d'autiste
Pour info, je passe mes journées à faire des requêtes de ce type
|
Marsh Posté le 26-06-2003 à 17:27:41
MagicBuzz a écrit : Bah j'ai rien à foutre là
|
effectivement c joli
moi je crois que je vais en faire pas mal dans les tps a venir mais je commence juste c pour ca que g du mal
je connais pas trop mal sql mais tout ce qui est oracle m'est inconnu...
Marsh Posté le 26-06-2003 à 12:46:57
J'utilise Oracle et des feuilles de style Xsl
je recupere mes valeurs par l'intermediaire d'un formulaire
je dois tester une valeur récupérée
cette valeur est comprise entre 1 et 5
entre 1 et 4 : je fais juste where mon_attribut=la_valeur_renvoyee_par_le_formulaire
si la valeur = 5 ca se complique
je dois faire le test avec la valeur 4 et faire un autre test supplémentaire :
where mon_attribut=4 and autre_condition
pour faire la 1ere condition j'utilise un replace mais pour la 2eme si j'inclus le test avec un OR quand la valeur = 5, la requete ne se termine jamais...
comment je pe faire cette condition?
aidez moi SVP