Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Salut à tous,
J'ai une Datawindow sur laquelle je voudrais faire un retrieve.
Le problème c'est que dès que j'arrive à ce retrieve, PB se plante.
J'ai copié la requête de la datawindow et j'ai essayé de l'exécuter directement sur Oracle, le message suivant est affiché : "RESULT SET EXCEEDS TNE MAXIMUM SIZE ( 100 MB) ".
J'ai essayé de retrouver le nombre de lignes retrouvées par la requête ( j'ai remplacé le select de la requête par count(*) ) , le résultat est : 220.000 lignes !!
J'ai pensé à "diviser" le résultat du retrieve ( puisqu'on peut faire des retrieve successifs sur la même datawindow ) mais je vois pas trop comment m'y prendre.
P.S. : La solution de diminuer le retour de la requête en rajoutant des clauses WHERE n'est pas envisageable car même si ça peut marcher, ce n'est pas une solution définitive car la base est régulièrement alimentée.
Merci d'avance !
Dernière modification par cannavaro (09-06-2008 13:48:11)
Hors ligne
Bonjour, regarde du coté de Retrieve.AsNeeded DataWindow object property
Hors ligne
Bonjour Cannavaro,
Tu peux utiliser la propriété Retrieve.AsNeeded en la positionnant à Yes.
[Edit] Grillé par erasorz
Hors ligne
Salut à vous deux et merci pour votre aide,
en fait, j'ai essayé retrieve.asneeded, en utilisant cette option, PB ne se plante pas mais me retourne uniquement 16 rows ( sur 250.000 rows ! ) alors que j'ai besoin de toutes les lignes , est-ce que je doit boucler ??
Je crois que je n'ai pas bien compris comment utiliser cette option.
Hors ligne
cannavaro a écrit:
Salut à vous deux et merci pour votre aide,
en fait, j'ai essayé retrieve.asneeded, en utilisant cette option, PB ne se plante pas mais me retourne uniquement 16 rows ( sur 250.000 rows ! ) alors que j'ai besoin de toutes les lignes , est-ce que je doit boucler ??
Je crois que je n'ai pas bien compris comment utiliser cette option.
Je crois que c'est en fonction de la où tu te trouve sur la DW. Tu as mis une Scrollbar verticale ?
Hors ligne
En fait, ma datawindow est de de type tabular, donc pas de Scrollbar
Hors ligne
La propriété Retrieve.AsNeeded retourne seulement le nombre de lignes suffisant pour s'afficher totalement dans la datawindow. Pour récupérer les lignes suivantes, il suffit de faire défiler la scrollbar verticale de la datawindow (A noter que le type de datawindow n'a strictement rien à voir avec la présence ou non d'une scrollbar: si tu ne définis pas dans les propriétés du controle qu'il faut afficher une scrollbar, tu n'en auras pas)
Pour plus d'infos:
Hors ligne
foon a écrit:
La propriété Retrieve.AsNeeded retourne seulement le nombre de lignes suffisant pour s'afficher totalement dans la datawindow. Pour récupérer les lignes suivantes, il suffit de faire défiler la scrollbar verticale de la datawindow (A noter que le type de datawindow n'a strictement rien à voir avec la présence ou non d'une scrollbar: si tu ne définis pas dans les propriétés du controle qu'il faut afficher une scrollbar, tu n'en auras pas)
Pour plus d'infos:
Ok, mais dans mon cas, la datawindow est invisible, je n'ai pas besoin de l'afficher, je voudrais juste la remplir avec le résultat de son select et par la suite , je vais exploiter les données qui y sont stockées.
Donc à priori, si j'utilise l'option AsNeeded, je ne pourrai exploiter que les 16 premières lignes retrouvées alors que je voudrai exploiter les 250.000 lignes qui devraient être retournées par ma requête ! C'est pourquoi je voulais savoir si je peux éventuellement boucler pour passer aux 16 lignes suivantes.
Dernière modification par cannavaro (09-06-2008 14:57:11)
Hors ligne
Tu as essayé en codant un Scrolltorow à la dernière ligne affichée + 1 jusqu'à ce qu'il n'y ait plus de lignes à charger?
Hors ligne
foon a écrit:
Tu as essayé en codant un Scrolltorow à la dernière ligne affichée + 1 jusqu'à ce qu'il n'y ait plus de lignes à charger?
Ah non, ça c'est une bonne idée, je vais l'essayer tout de suite
Dernière modification par cannavaro (09-06-2008 15:12:05)
Hors ligne
cannavaro a écrit:
P.S. : La solution de diminuer le retour de la requête en rajoutant des clauses WHERE n'est pas envisageable car même si ça peut marcher, ce n'est pas une solution définitive car la base est régulièrement alimentée.
Sans connaitre exactement ce que tu veux faire c'est difficile de te répondre mais est tu sur et certain d'avoir besoin de récupérer autant de lignes ?
si oui tu peux aussi voir si tu retrieve uniquement les colonnes dont tu as besoin (pas besoin de ramener toutes les colonnes d'une table si il n'y a que l'id de la ligne et par exemple une colonne "montant" qui seront utilisés par après.
Je ne comprends pas le "car même si ça peut marcher, ce n'est pas une solution définitive car la base est régulièrement alimentée."
Admettons par ex que tu fasse une procédure pour calculer des salaires j'imagine que dans ton query tu vas ajouter une clause where sur l'année voulue pour le calcul et donc éviter de récupérer à chaque fois toutes les lignes de ta DB.
Car même si tu arrives à t'en sortir avec Retriev As Needed je pense que c'est partir sur une solution "bricolage" que tu risques de regretter par après et de plus tu vas mettre le PC qui va faire tourner ça sur les genoux vu que il va devoir swapper comme un dingo pour gérer autant d'infos.
My 2 cents, sais pas si ça peut aider
Dernière modification par rincevent (09-06-2008 15:33:25)
Hors ligne
rincevent a écrit:
Sans connaitre exactement ce que tu veux faire c'est difficile de te répondre mais est tu sur et certain d'avoir besoin de récupérer autant de lignes ?
Bien vu!
Sans savoir ce que Canavarro veut faire, on peut facilement affirmer qu'il n'en a pas besoin.
J'irai même plus loin : c'est une erreur fondamentale d'architecture de vouloir ramener 220 000 lignes.
Canavarro, pourquoi pense tu devoir ramener autant de ligne s?
Hors ligne
Je pense effectivement qu'il y a un problème de conception à la base du problème.
Malgré tout, si tu veux vraiment charger tes 220000 lignes dans PB (aïe la mémoire du poste), tu peux quand même ajouter 2 arguments à ton retrieve : li_min, li_max et ajouter dans le where de ta requette oracle where rownum >= li_min and rownum <= li_max.
Ainsi tu pourras ramener des blocs de lignes de ton resultset et les traiter un par un. Ex : retrieve(arg1, arg2, 0, 10000) puis retrieve(arg1, arg2, 10001, 11000), etc...
Hors ligne
shahin a écrit:
rincevent a écrit:
Sans connaitre exactement ce que tu veux faire c'est difficile de te répondre mais est tu sur et certain d'avoir besoin de récupérer autant de lignes ?
Bien vu!
Sans savoir ce que Canavarro veut faire, on peut facilement affirmer qu'il n'en a pas besoin.
J'irai même plus loin : c'est une erreur fondamentale d'architecture de vouloir ramener 220 000 lignes.
Canavarro, pourquoi pense tu devoir ramener autant de ligne s?
Non désolé mon ami, c'est pas bien vu.
En fait, j'ai pas choisi de ramener tant de lignes, et je ne peux pas diminuer les informations qui se trouvent dans le select .
Pour vous expliquer un peu plus la situation , j'ai des opérations sur des portefeuilles que je dois récupérer à partir d'un etable de la base.
mais le nombre d'opérations sur un portefeuille est très variable, en plus, ça s'accumule au fur et à mesure que de nouvelles opérations sont effectuées sur un portefeuille.
Hors ligne
Chrnico a écrit:
Je pense effectivement qu'il y a un problème de conception à la base du problème.
Malgré tout, si tu veux vraiment charger tes 220000 lignes dans PB (aïe la mémoire du poste), tu peux quand même ajouter 2 arguments à ton retrieve : li_min, li_max et ajouter dans le where de ta requette oracle where rownum >= li_min and rownum <= li_max.
Ainsi tu pourras ramener des blocs de lignes de ton resultset et les traiter un par un. Ex : retrieve(arg1, arg2, 0, 10000) puis retrieve(arg1, arg2, 10001, 11000), etc...
long ll_count long ll_pas = 10000 long ll_i = 1 do while ll_count > 0 ll_count = ma_dw.retrieve(arg1, arg2, ..., 1 + (ll_pas * (ll_i - 1)), ll_i * ll_pas) ll_i ++ // Je traite mon bloc de lignes loop
Hors ligne
cannavaro a écrit:
Ok, mais dans mon cas, la datawindow est invisible, je n'ai pas besoin de l'afficher, je voudrais juste la remplir avec le résultat de son select et par la suite , je vais exploiter les données qui y sont stockées.
Une question en passant: Tu ne peux pas créer une procédure sur ton serveur pour gérer directement tes données dessus?
En règle générale, il vaut mieux déporter un maximum de traitements sur le serveur (surtout s'ils sont lourds).
En Oracle, par exemple, il existe suffisamment de possibilités pour te permettre de gérer correctement de telles quantités
de données (GTT, curseurs, etc...)
Hors ligne
De plus, je pense necessaire d'attirer votre attention sur un des danger du retrieveAsNeeded : si ta datawindow partage sa transaction avec au moins une autre, il faut eviter le retrieveAsNeeded, car alors un curseur restera ouvert sur ton serveur, dans le but de recuperer progressivement le reste des lignes, ce qui poserait de gros probleme si la meme transaction recevait entre temps d'autre SQL statements (insert, update,...). Je ne sais pas en Oracle, mais en SQL Server et ASA c'est un probleme de conception recurrent... Apres tout, c'est du dirty fixing
De toute facon, je crois que la question ne se pose pas, dans ton cas, tu dois absolument suivre le conseil de Foon: procedure, procedure, procedure! Si ton resultSet fait vraiment 100Mb, tu n'aura aucune maniere de ne pas saturer le poste client qui aura le malheur de lancer ton retrieve...
Good luck
Hors ligne
Cortex a écrit:
De toute facon, je crois que la question ne se pose pas, dans ton cas, tu dois absolument suivre le conseil de Foon: procedure, procedure, procedure! Si ton resultSet fait vraiment 100Mb, tu n'aura aucune maniere de ne pas saturer le poste client qui aura le malheur de lancer ton retrieve...
Agree.
Hors ligne
Je suis assez d'accord avec vous. Si le but est de traiter le resultset pour en extraire une information condensée ou faire de la mise à jour en base, autant le faire en procédure stockée , mais malheureusement ce n'est pas toujours le cas. Surtout en banque...
Par exemple, si notre amis cherche à alimenter une position dans une autre application via un feed (Tibco RdV, MQSeries ou Swift par exemple), il devra bien extraire ses données de la base à un moment ou un autre... Et là pas moyen de faire l'impasse. Reste à morceller le resultset pour le traiter par bloc. Pour cela, le RetrieveAsNeeded n'est pas la solution (datastore), mais l'utilisation du rownum Oracle me semblait un bon moyen...
Hors ligne
Merci pour tous vos conseil, donc je vais laisser tomber la solution AsNeeded et je vais opter pour le RowNum, espérons que ça va marcher .
A suivre ...
Hors ligne