Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sql*Plus Oracle Discussion :

Saut de page


Sujet :

Sql*Plus Oracle

  1. #1
    Nouveau Candidat au Club
    Saut de page
    Bonjour la communauté,
    Je suis nouveau sur le forum
    Je travaille sur un script qui génère des résultats à imprimer.
    Oracle 10g
    J'ai une requette avec un select sous forme:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    set linesize 136
    set pagesize 60
    set ...
     
    column xxx
    column xxxx
    ttitle left 'lll' right 'rrr' skip 1-    
    ...
    spool fichier.lst
     
    select chp1,chp2,chp3 
    from tab1
    where cdt1 and cdt2...
    order by chp1
    ;
    spool off
    exit

    cette requette me retourne par exemple un résultat sous forme:

    Titre
    ...


    res01 res12 res13
    res01 res14 res15
    res01 res16 res17

    res02 res22 res23

    res03 res32 res33
    res03 res34 res35
    res03 res36 res37
    res03 res38 res39
    y a t il une astuce ou possibilité d’intégrer un script (ou autre chose) dans le select // ou intégrer le select dans un script pour avoir des résultats par page
    les 3 résultats "res01" dans une première page
    le résultat "res02" dans une deuxième page
    les 4 résultats "res03" dans une troisième page

    Le but c'est d'avoir un fichier imprimable
    Si quelqu'un peut m'orienter vers une piste
    Merci d'avance

  2. #2
    Membre averti
    Bonjour,

    Tu peux faire une jointure externe avec un row generator de 60 lignes. Est-ce que tes groupes de lignes feront toujours moins de 60 lignes?
    Tu peux aussi passer un script au niveau OS pour faire cette opération. C'est quoi ton OS?

  3. #3
    Nouveau Candidat au Club
    Bonjour vanagreg et merci pour ton intérêt
    Oui les groupes font moins de 60 lignes
    Au maximum 15 lignes par groupe
    L'OS c'est AIX 5.3
    J'utilise putty pour l'execution du script depuis mon pc
    Peux tu stp me fournir plus d'explication sur le manière d'utiliser un row generator ou sur le script OS

  4. #4
    Expert éminent
    J'ai réussi à faire ce que dit Vanagreg, mais ce n'est peut être pas la meilleure solution sql

    Exemple
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT cluster_name, table_name
    FROM all_tables 
    WHERE owner ='SYS' AND cluster_name IS NOT NULL  AND cluster_name <> 'C_OBJ#' 
    ORDER BY cluster_name, table_name


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    CLUSTER_NAME	TABLE_NAME
    C_COBJ#	CCOL$
    C_COBJ#	CDEF$
    C_FILE#_BLOCK#	SEG$
    C_FILE#_BLOCK#	UET$
    C_MLOG#	MLOG$
    C_MLOG#	SLOG$
    C_OBJ#_INTCOL#	HISTGRM$
    C_RG#	RGCHILD$
    C_RG#	RGROUP$
    C_TOID_VERSION#	ATTRIBUTE$
    C_TOID_VERSION#	COLLECTION$
    C_TOID_VERSION#	METHOD$
    C_TOID_VERSION#	PARAMETER$
    C_TOID_VERSION#	RESULT$
    C_TOID_VERSION#	TYPE$
    C_TS#	FET$
    C_TS#	TS$
    C_USER#	TSQ$
    C_USER#	USER$
    SMON_SCN_TO_TIME_AUX	SMON_SCN_TIME


    si tu veux faire 1 page par Cluster_name, il faut avoir 60 lignes par cluster_name (sous réserve que tu n'aies pas plus de 60 lignes (sinon, faut aussi gérer les multiples pages par cluster)

    cette requête va fournir le n° de page et le n° de ligne dans la page
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT cluster_name, table_name, row_number() OVER (PARTITION BY cluster_name ORDER BY table_name) numligne,
    		DENSE_RANK() OVER (ORDER BY cluster_name) nopage
    FROM all_tables 
    WHERE owner ='SYS' AND cluster_name IS NOT NULL AND cluster_name <> 'C_OBJ#' 
    order by cluster_name, table_name


    Il faut ensuite faire une jointure externe avec une table contenant le nombre total de ligne de toutes les pages
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    (SELECT LEVEL AS num FROM dual connect BY LEVEL <= 60*:nbpage_total)


    Seul problème, avoir le nombre de pages. Sans refaire une requête, il faudrait peut être utiliser des with recursifs

    Du coup la requête n'est pas très propre
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT cluster_name, table_name, nopage, numligne, l.num
    FROM (
    SELECT cluster_name, table_name, row_number() OVER (PARTITION BY cluster_name ORDER BY table_name) numligne,
    		DENSE_RANK() OVER (ORDER BY cluster_name) nopage
    FROM all_tables 
    WHERE owner ='SYS' AND cluster_name IS NOT NULL AND cluster_name <> 'C_OBJ#' 
    ) w, (SELECT LEVEL AS num FROM dual 
    			connect BY LEVEL <= (SELECT 60 * COUNT(DISTINCT cluster_name) FROM  all_tables 
    							WHERE owner ='SYS' AND cluster_name IS NOT NULL AND cluster_name <> 'C_OBJ#') )  l
    WHERE l.num = 60 * (w.nopage(+) -1) + w.numligne(+)
    ORDER BY l.num
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB

  5. #5
    Nouveau Candidat au Club
    Merci McM pour tes explications
    C'est plus clair maintenant
    Je vais tester tout ça
    Merci à vous

  6. #6
    Expert éminent
    Bonjour,
    SQL*Plus a plein de fonctions pour ça, comme BREAK ON ... SKIP PAGE combiné avec SET PAGESIZE
    https://docs.oracle.com/en/database/...0-5C42C546534F
    Franck Pachot - dbi services - Oracle ACE Director - OCM 12c - Oak Table member - twitter: @FranckPachot - blog: blog.pachot.net

  7. #7
    Membre averti
    Bonjour,

    en SQL, il suffit simplement de faire un PARTITION OUTER JOIN. Cette requête devrait répondre à ton besoin:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select chp1, chp2, chp3
    from
    (select chp1,chp2,chp3, dense_rank() over (order by chp1) dr
     from tab1
     where cdt1 and cdt2...
    ) v1  
    partition by (v1.dr)
    right outer join (select level lvl from dual connect by level <= 60) v2
    on (v1.dr = v2.lvl)                      
    order by dr, lvl;



    La fonction DENSE_RANK va générer un numéro de "groupe" pour chaque rupture sur la colonne CHP1. Elle va permettre de faire une jointure externe partitionnée (PARTITION OUTER JOIN) sur la vue v2 qui ne fait que générer 60 lignes avec la colonne lvl incrémentale. La jointure partitionnée fait en sorte de joindre la vue v1 par partitions (et non sur l'ensemble des lignes), ce qui permet de créer 60 lignes à chaque fois par groupe. Ainsi, tu auras N lignes non vides de chaque CHP1 suivies de 60-N lignes vides.