In alcune situazioni può essere necessario conoscere in anticipo il numero di record che si stanno per leggere e presentare all’utente. Pensiamo per esempio ad applicazioni realizzate per il Web, dove un elenco viene mostrato a gruppi e a video compaiono dei pulsanti per spostarsi da una pagina all’altra. Esempio:
Qui si nota come compaia già il numero totale di elementi visualizzabili, mostrati a gruppi di 10 per volta.
Per estrarre i dati è necessario definire un cursore SQL e caricare tutti i record letti in una schiera di DS, gestendo poi il posizionamento pagina per pagina.
Il conteggio si può ottenere impostando in una variabile il risultato di una COUNT(*) a fronte di uno statement che contenga gli stessi criteri di estrazione del cursore definito in precedenza.
Esiste però una soluzione più efficace, che ci evita di scrivere due istruzioni praticamente uguali…
L’istruzione GET DIAGNOSTICS restituisce numerose informazioni relative all’ultima istruzione SQL eseguita. Qui la documentazione dettagliata da IBM. Nel nostro caso, l’informazione che ci interessa è DB2_NUMBER_ROWS che, eseguita dopo la OPEN di un cursore, contiene il numero di righe della tabella risultante dalla selezione.
Exec SQL
GET DIAGNOSTICS :righe = DB2_NUMBER_ROWS ;
Ecco un esempio di semplice programma che dichiara una query SQL e reperisce il numero di righe:
//
// Conteggio righe con GET DIAGNOSTICS - DB2_NUMBER_ROWS
//
// *ENTRY PLIST
dcl-pi FAQ40001 ;
end-pi;
dcl-s righe packed(5:0);
*inLR=*on;
Exec SQL
SET OPTION Commit = *none,
CloSqlCsr=*EndMod,
DlyPrp=*YES
;
Exec SQL
DECLARE c1 CURSOR FOR
SELECT
m.tipoArt, m.articolo, descrizione,
codMag, dataMovimento, segno, m.um, quantita
FROM mduca1.movmag00f m
LEFT JOIN mduca1.anaart00f a ON
(m.tipoArt, m.Articolo)=(a.tipoArt, a.Articolo)
WHERE quantita > 50
;
Exec SQL
OPEN c1;
Exec SQL
GET DIAGNOSTICS :righe = DB2_NUMBER_ROWS;
dsply ('RIGHE = ' + %char(righe)) ;
return;
Lanciando il programma a fronte di un database di test, questo è il risultato:
DSPLY RIGHE = 409
Premere Invio per continuare.
Andiamo a verificare eseguendo la stessa query da una sessione SQL, selezionando il solo conteggio dei record:
Ma… c’è qualcosa che non quadra ! Per una stessa query il programma trova 408 righe, e l’SQL ne trova 448 ?
La risposta a questa “stranezza” la dà il manuale IBM: per cursori di tipo “dinamico” (come quello visto sopra) il valore restituito in DB2_NUMBER_ROWS è da considerarsi una approssimazione, in quanto eventuali righe inserite o cancellate possono avere impatto sul set di risultati finale.
Per ottenere il numero esatto di righe occorre quindi definire esplicitamente il cursore come “INSENSITIVE”; in questo modo il set di risultati viene “congelato” al momento dell’apertura del cursore e le eventuali modifiche alle tabelle refenziate nell’istruzione non avranno effetto. I cursori di tipo INSENSITIVE non possono essere usati per operazioni di aggiornamento o cancellazione.
Exec SQL
DECLARE c1 INSENSITIVE CURSOR FOR
ecc...
Rilanciamo il programma dopo la modifica… ed ora finalmente tutto quadra !
Visualizzazione messaggi del programma
DSPLY RIGHE = 448
Premere Invio per continuare.
Attenzione: se si gestisce la paginazione direttamente nel cursore SQL (con le parole chiave LIMIT o FETCH FIRST n ROWS ONLY e OFFSET), GET DIAGNOSTICS non restituirà il totale delle righe del set di risultati, ma solo quelle specificate nella clausola LIMIT. Per ottenere il totale sarà quindi necessario definire un secondo cursore senza la clausola di limitazione del numero di righe lette.
Con questo post voglio consigliarti la lettura di questo articolo di Giancarlo Lui sulla TechXChange Community: IBM i System Management:…
Nel suo recente articolo "Option *convert in RPG Free" , Aldo Succi esplora l'opzione *CONVERT nel linguaggio RPG, evidenziando come…
Guida pratica all'aggiornamento dei certificati Java e DCM per consumo web services via SQL HTTPGETCLOB e HTTP_GET.
Riceviamo e pubblichiamo ben volentieri questo "tip & trick" di Patrick Rizzi che presenta una tecnica che permette di intervenire…
Prendo spunto da una risposta di Michael Mayer sulle mailing list di Midrange.com a chi chiedeva come monitorare i messaggi…
Le imprese sono sempre più alla ricerca di strumenti che possano migliorare l'efficienza, la collaborazione e la gestione delle risorse.…