Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour à tous,
Je ne sais pas est-ce qu’il s’agit d’un bug PB ou non !
J’ai un problème avec une requête SQL embarqué dans le code PB, le système ne tient pas compte le dernier AND dans la clause WHERE, mais ce qu’est bizarre c’est que j’arrive pas à reproduire le bug sur nos machines !!! Le problème présente seulement chez le client.
J’ai essayé même à installer le même environnement que le client mais toujours le même PB.
Nous et le client on a :
DLLs de PB 10.5.1 Build 6602
Oracle 9
Merci à vous de me communiquer le Numéro de l’EBF s ‘il s’agit d’un Bug.
Dernière modification par mattdamon (02-11-2009 10:39:43)
Hors ligne
J'ai oublié une chose importante, quand je déplace le dernier AND au début de la clause where le système fonctionne correctement.
Hors ligne
On peut voir le script complet avec la requête? Merci d'avance
Hors ligne
foon a écrit:
On peut voir le script complet avec la requête? Merci d'avance
// *** Recherche de la priorité maxi SELECT MAX (priorite) INTO :li_priorite_maxi FROM op.parametrage WHERE (portefeuille = :ls_portefeuille OR portefeuille IS NULL) AND (secteur_eco = :ls_secteur_eco OR secteur_eco IS NULL) AND (compte_actif = :ls_compte_actif OR compte_actif IS NULL) AND (classe_inventaire = :ls_classe_inventaire OR classe_inventaire IS NULL) AND (categorie = :ls_categorie OR categorie IS NULL) AND (marche = :ls_marche OR marche IS NULL) AND (garantie = :ls_garantie OR garantie IS NULL) AND ( (pays_ocde = 'O' AND :ls_pays_ocde IN (SELECT code FROM op.table_liste_codes WHERE num_table = :num_table AND liste = :ls_ocde)) OR (pays_ocde = 'N' AND :ls_pays_ocde NOT IN (SELECT code FROM op.table_liste_codes WHERE num_table = :num_table AND liste = :ls_ocde)) OR (pays_ocde IS NULL) ) AND (plan_comptable = :ls_plan_comptable);
le problème dans
AND (plan_comptable = :ls_plan_comptable)
;quand je déplace cette ligne au début, il fonctionne.
Dernière modification par mattdamon (02-11-2009 11:31:42)
Hors ligne
Je suppose que tu as testé sur une copie de la base de ton client.
Vérifie cependant que la "table op.parametrage" est bien conforme à ce que tu attends.
Le test du code retour donne quoi quand ça ne marche pas?
NB: J'espère que ta table "op.table_liste_codes" n'est pas très grande, parceque les temps de traitement des
clauses IN et NOT IN risquent d'être particulièrement longs. Il faudrait peut-être optimiser un peu tout ça
NB2: C'est normal que tu ne testes pas "plan_comptable" à NULL?
Hors ligne
foon a écrit:
Je suppose que tu as testé sur une copie de la base de ton client.
Vérifie cependant que la "table op.parametrage" est bien conforme à ce que tu attends.
Le test du code retour donne quoi quand ça ne marche pas?
NB: J'espère que ta table "op.table_liste_codes" n'est pas très grande, parceque les temps de traitement des
clauses IN et NOT IN risquent d'être particulièrement longs. Il faudrait peut-être optimiser un peu tout ça
NB2: C'est normal que tu ne testes pas "plan_comptable" à NULL?
Oui, je teste sur une copie de la base de client. toutes les tables sont conformes.
Si le système tient comptes le : AND (plan_comptable = :ls_plan_comptable);
la valeur li_priorite_maxi doit être égale = null
Puisque le système ne tient pas compte la condition, donc le résultat li_priorite_maxi = 96, c'est la valeur quand j'exécute seulemnt la requete sans le AND.
la table op.table_liste_codes contient seulemnt 30 lignes.
Que pensez vous ?
Hors ligne
Si tu places ta clause AND (plan_comptable = :ls_plan_comptable)
avant les clauses IN et NOT IN, est-ce que ça marche?
Hors ligne
foon a écrit:
Si tu places ta clause AND (plan_comptable = :ls_plan_comptable)
avant les clauses IN et NOT IN, est-ce que ça marche?
Oui
Hors ligne
Fais un explain plan sur les deux versions de la requête.
Tu auras peut-être des surprises.
Hors ligne
foon a écrit:
Fais un explain plan sur les deux versions de la requête.
Tu auras peut-être des surprises.
J'ai oublié d'expliquer quelque chose importante...
En fait, j'ai demandé une copie de la base de données de client, je l'ai installé sur notre serveur oracle, je me connecte avec la même version de notre application ---> le système fonctionne correctement (il tient en compte la clause where)
Le problème présente seulement chez le client, le système chez lui ne tient pas en compte la clause WHERE citée ci-dessus.
J'ai pas trouvé une explication logique, pour cela que j'ai douté de la version de build et bug dans PB...
Que pensez-vous foon ?
Hors ligne
Chez le client, ils se connectent à la base via le driver natif Oracle, ou via ODBC?
Tu as fais une trace pour voir si, par hasard, la requête ne retourne pas un "No Data Found" chez le client?
Hors ligne
foon a écrit:
Chez le client, ils se connectent à la base via le driver natif Oracle, ou via ODBC?
Tu as fais une trace pour voir si, par hasard, la requête ne retourne pas un "No Data Found" chez le client?
Je crois que la connexion via le driver natif Oracle.
exactement, il dois nous envoyer une trace...c'est la dernière chose à faire
Hors ligne
Essaye cette requete, je pense qu'le va te donner un bien meilleur temps de réponse et un résultat correct :
SELECT MAX (priorite) INTO :li_priorite_maxi
FROM op.parametrage
WHERE (portefeuille = :ls_portefeuille OR portefeuille IS NULL)
AND (secteur_eco = :ls_secteur_eco OR secteur_eco IS NULL)
AND (compte_actif = :ls_compte_actif OR compte_actif IS NULL)
AND (classe_inventaire = :ls_classe_inventaire OR classe_inventaire IS NULL)
AND (categorie = :ls_categorie OR categorie IS NULL)
AND (marche = :ls_marche OR marche IS NULL)
AND (garantie = :ls_garantie OR garantie IS NULL)
AND (plan_comptable = :ls_plan_comptable)
AND (
(
pays_ocde = 'O' AND Exists (
select 1
from op.table_liste_codes
where code = :ls_pays_ocde
AND num_table = :num_table
AND liste = :ls_ocde
AND Rownum = 1
)
)
OR (
pays_ocde = 'N' AND Not Exists ( Select 1
from op.table_liste_codes
where code = :ls_pays_ocde
AND num_table = :num_table
AND liste = :ls_ocde
AND Rownum = 1
)
)
OR (pays_ocde IS NULL)
)
;
Hors ligne
Merci pour la requête, mais n'oubliez pas les balises (sans espaces) [ code=sql ][ /code ]
Hors ligne
J'oubliais ceci :
NVL(expr_1, expr_2)
Prend la valeur expr_1, sauf si expr_1 est NULL auquel cas NVL prend la valeur expr_2.
Une valeur NULL en SQL est une valeur non définie.
Lorsque l'un des termes d'une expression a la valeur NULL, l'expression entière prend la valeur NULL. D'autre part, un prédicat comportant une comparaison avec une expression ayant la valeur NULL prendra toujours la valeur faux. La fonction NVL permet de remplacer une valeur NULL par une valeur significative.
DE ce fait, je propose ceci : tu remplaces la clause
OR (pays_ocde IS NULL) par ceci : OR ( NVL(pays_code,'XXX') = 'XXX' )
Et voilà, je pense que là ta requete est à la fois optimisé et doit répondre à tout ce dont tu as besoin.
A plus
Hors ligne
Oup's, un loupé avec mon clavier
c'est , OR (NVL(pays_ocde,'XXX') = 'XXX')
Hors ligne