Dalla versione V5R4 del nostro System i è disponibile la funzione SQL ROW_NUMBER() OVER() che ci viene in aiuto per l’esecuzione di query in modalità paginata.
La paginazione di un resultset è un operazione particolarmente utile quando si lavora in ambiente web poichè, per diminuire i tempi di risposta dell’applicativo. si dovrebbero far transitare pochi byte di dati ad ogni iterazione tra client e server.
La funzione ROW_NUMBER() OVER() specifica che un numero di riga sequenziale dev’essere aggiunto al resultset partendo da 1 per la prima riga.
OVER(..) accetta una clausola di ORDER BY sulla quale la funzione ROW_NUMBER(..) si baserà per generare la sequenza.
Al fine di interrogare in modalità paginata un resultset manterremo all’interno di OVER() la stessa clausola di ordinamento della query di partenza:
SELECT ROW_NUMBER() OVER (ORDER BY CAMPO2 DESC) AS NUMERO_RIGA, CAMPO1, CAMPO2 FROM TABELLA ORDER BY CAMPO2 DESC
Ecco un esempio per paginare il resultset di una query generica che estrae i campi NRMOV (numero movimento) DAMOV(data movimento) e QTMOV(quantità movimentata) di una ipotetica tabella di movimenti:
SELECT NRMOV, DAMOV, QTMOV FROM MOVIMENTI ORDER BY NRMOV DESC
Aggiungiamo una colonna ROWNUMBER, che conterrà i valori generati dalla funzione ROW_NUMBER() OVER():
SELECT ROW_NUMBER() OVER(ORDER BY NRMOV DESC) ROWNUMBER, NRMOV,DAMOV,QTMOV FROM MOVIMENTI ORDER BY NRMOV DESC
Incapsuliamo la query in una sottoquery per poter poi applicare una condizione di WHERE sulla colonna appena aggiunta:
SELECT * FROM( SELECT ROW_NUMBER() OVER(ORDER BY NRMOV DESC) ROWNUMBER, NRMOV,DAMOV,QTMOV FROM MOVIMENTI ORDER BY NRMOV DESC ) TEMP WHERE TEMP.ROWNUMBER BETWEEN 1 AND 10
Ipotizzando di voler pagine da 10 record ciascuna, per estrarre la prima pagina di dati dobbiamo ottenere i record che hanno il campo ROWNUMBER compreso tra 1 e 10; la seconda pagina, analogamente, conterrà i record con ROWNUMBER compreso tra 11 e 20:
WHERE TEMP.ROWNUMBER BETWEEN 11 AND 20
la terza tra 21 e 30, e così via:
WHERE TEMP.ROWNUMBER BETWEEN 21 AND 30
L’esempio è particolarmente semplice ma può essere generalizzato per qualsiasi tipo di interrogazione.
In un prossimo articolo vi mostro come sarà possibile generalizzare la costruzione della query tramite PHP su IBM i per poi eseguirla con le funzioni db2_ presenti nativamente in seguito all’installazione di ZendServer for IBM i.