PL/SQL Affichage par page. [ORACLE] - SQL/NoSQL - Programmation
Marsh Posté le 05-02-2003 à 12:21:31
C'est sûr que c'est difficile de manipuler des enregistrements triés avec rownum.
Mais es-tu obligé de faire cela par le SQL ? Dans le principe, on renvoie le jeu d'enregistrements à l'application cliente, charge à elle de les présenter comme elle l'entend.
Si c'est pour imprimer directement à partir de SqlPlus, utilise de préférence les commandes de mises en page qui sont assez puissantes (par exemple, SET PAGESIZE x pour x enregistrements par page).
Dans des procédures stockées, tu peux utiliser les curseurs pour controler facilement des paquets enregistrements. C'est ce que je fais pour parallèliser des traitements sur des grosses tranches d'enregistrements sans chevauchement.
J'ai pas de solution meilleure que la tienne. Pour des petits rapports vite fait, en général je m'arrange pour exporter le résultat complet vers un fichier que je retraite en fonction de son contenu.
Marsh Posté le 05-02-2003 à 14:27:35
En fait je code çà dans des prodédures stockées qui sont appelées par des appli minitel ou web.
Les applis donnent en entrée le numéro de page voulu avec le nombre de lignes par page, et la proc retourne des 'TABLE OF VARCHAR2' pour chaque champ, ainsi que le nombre de pages dispo suivant le nombre de ligne max.
Bien sûr au premier appel, le numéro de page doit être 1.
Evidement, le minitel et le WEB ne gèrent pas le même nombre de lignes par page.
Je ne peut pas me permettre d'envoyer la totalité des enregs aux applis à chaque fois...
D'autre part, faire un curseur, puis boucler dans le vide pour passer les premiers enregistrement est une hérésie complète par rapport à une requête comme celle que je fait. Même avec 3 requêtes imbriquée, le moteur SQL d'oracle encore beaucoup plus efficace qu'une boucle PL/SQL pour sauter les premier enregs. Surtout quand y'en a beaucoup beaucoup!
En tout cas merçi d'avoir fait remonter mon post
Marsh Posté le 05-02-2003 à 14:31:10
J'avais pas bien lu :
"tu peux utiliser les curseurs pour controler facilement des paquets enregistrements"
Comment tu fais pour limiter l'action du cuseur sur une 'fenêtre' particulière ? ? ?
Marsh Posté le 05-02-2003 à 14:38:03
Mara's dad a écrit : J'avais pas bien lu : |
Je pense que tu dois pouvoir utiliser des fonction sur les ROWID via le package DBMS_ROWID :
Citation : Extended ROWIDs |
en particulier, tu as la fonction ROWID_ROWNUMBER qui te retourne le numéro de l'enregistrement.
Marsh Posté le 05-02-2003 à 15:18:53
C'est gentil de pense à moi, mais les ROWID ne sont pas utilisables. Ils sont spécifiques à chaque table, et mes requêtes portent sur plusieurs tables ( Ce que je n'avais pas indiqué il est vrai ).
D'autre part la fonction ROWID_ROWNUMBER me retourne le numéro d'ordre de l'enregistrement dans une table. Moi, j'ai besoin d'un numéro d'ordre commançant à 1 pour ma requête et s'incrémentant de 1 en 1 à chaque ligne. C'est ce que fait le ROWNUM, à condition de le sortir pour qu'il prennent en compte la clause "ORDER BY".
Décidément, plus je cherche et plus je panse qu'il n'y a pas d'autre solution.
Marsh Posté le 04-02-2003 à 17:43:40
-- Pour avoir le nombre d'enregistrement.
SELECT COUNT(*)
FROM
CptMouvement,
CptTransaction
WHERE
CptMouvement.COMPTE_ROBID = 6180
AND CptTransaction.robId = CptMouvement.TRANSACTIONFIN_ROBID
AND CptTransaction.dateCreation < ( SYSDATE + 1 )
AND CptTransaction.dateCreation > ADD_MONTHS( SYSDATE + 1, -1 );
-- Pour avoir la troisième page de 10 enregistrements.
SELECT
*
FROM (
SELECT
ROWNUM x, a, b, c
FROM (
SELECT
CptTransaction.dateCreation a,
CptMouvement.Robid b,
CptMouvement.montant c
FROM
CptMouvement,
CptTransaction
WHERE
CptMouvement.COMPTE_ROBID = 6180
AND CptTransaction.robId = CptMouvement.TRANSACTIONFIN_ROBID
AND CptTransaction.dateCreation < ( SYSDATE + 1 )
AND CptTransaction.dateCreation > ADD_MONTHS( SYSDATE + 1, -1 )
ORDER BY
CptTransaction.dateCreation DESC
)
)
WHERE
x >= 21
AND x <= 30;
-----------------------------------------------------------------------------------------
Bonjour les gens
J'ai un peu cherché, et à force de ne pas trouver, j'ai inventé...
Quoi ? Ben un affichage par page pour les requêtes sous ORACLE.
Pour avoir 10 enregistrements à partir du 11ème, en MySql, c'est simple :
Avec Oracle, çà l'est Beaucoup MOINS !
Y'a bien une notion de ROWNUM, mais elle n'est pas très pratique à utiliser :
1- Le ROWNUM n'est généré que pour les enregistrements réellement retourné. Le premier est donc toujours 1.
Si on fait un WHERE ROWNUM > 10 par exemple, la requête ne retourne rien. En revanche, on peut mettre une limite supérieure.
2- Le ROWNUM est généré AVANT le ORDER BY, ce qui fait que dans les cas d'un affichage par page, on a un problème :
exemple :
SELECT ROWNUM, MONTANT, DATE FROM VENTES ORDER BY MONTANT DESC;
Si je limite ROWNUM à 5, (la première page) je voudrais avoir çà :
Mais en fait j'aurais çà :
Il faut donc trouver une solution pour les deux problèmes.
J'ai pas trouvé mieux que ce qui suit pour avoir, par exemple, la deuxième page ( par page de 10 ):
Ce qui fait quand même 3 requêtes imbriquées au minimum !
Ce que j'aimerai savoir, c'est si je me suis cassé la tête pour rien, ou si y'a pas de meilleur solution...
Message édité par Mara's dad le 04-02-2003 à 17:46:10
---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.