Una delle richieste fatte molto spesso dai clienti con cui sono abituato a lavorare e la possibilità di poter visualizzare i risultati di una ricerca impaginati, cioè presentare N records per pagina. Ora utilizzando Stored Procedure si potrebbero intraprendere due strade differenti ma solo una, secondo me, è la migliore.
- Cache memory
- Eseguire la stored procedure e caricare in memoria (cache) il risultato della query, successivamente quando l’utente utilizza i cursori, lo spostamento viene effettuato sui dati presenti in cache. Un idea pessima se il contesto in cui lavoriamo prevede enormi quantità di dati e di conseguenza grandi risultati nella ricerca, se poi proviamo a pensare ad un’applicazione web in cui il numero di utenti che la utilizza è davvero elevato potremmo trovarci davvero nei guai. Il traffico generato dalle richiesta inviate da/al Server SQL non solo rischia di portare la rete ad un congestionamento, ma è potrebbe bloccare anche il server stesso.
- SQL Cursors
- La seconda strada, secondo me la migliore, è quella di creare una stored procedure che implementi l’utilizzo dei cursori internamente alla query.
In questo post voglio spiegare (sperando di essere di aiuto per qualcuno) come scrivere una stored procedure che soddisfi quanto spiegato nel secondo punto. Supponiamo di voler raggiungere il seguente obiettivo: dati in input i parametri e la combinazione di cursori, la stored procedure deve tirar fuori un determinato numero di record.
Prendiamo in esame una semplice tabella (che per comodità conterrà secondo la nostra fantasia tanti tanti records!). Abbiamo la tabella Persona, che al suo interno contiene tre campi: ID, Nome e Cognome (si proprio la più semplice!). Ora dobbiamo creare una stored procedure che soddisfi il nostro obiettivo:
CREATE PROCEDURE CercaPersona @nome varchar(50) = null, @cognome varchar(50) = null, @rpp tinyint, @start int AS CREATE TABLE #T( ID int not null primary key IDENTITY(1,1), IDPersona int not null) INSERT INTO #T(IDPersona) SELECT ID FROM Persona WHERE ((Nome LIKE '%' + @Nome + '%') OR (@Nome IS NULL)) AND ((Cognome LIKE '%' + @Cognome + '%') OR (@Cognome IS NULL)) SELECT p.ID,p.Nome,p.Cognome FROM Persona AS p INNER JOIN #T AS t ON t.IDPersona = p.ID WHERE p.ID >= @start AND p.ID < (@start + @rpp) DROP TABLE #T go
Penso sia doveroso spiegare come funziona, prima di tutto analizziamo i parametri, oltre al Nome ed il Cognome che rappresentano chiaramente i parametri , ci sono anche:
- @rpp: questo parametro l'ho chiamato cosi proprio perchè è l'acronimo di righe per pagina, in pratica stiamo dicendo alla stored procedure quante righe vengono stampate in ogni pagina.
- @start: indica l'indice dell'elemento dei risultati da cui iniziare a leggere.
Osservando nella sua totalità la query si nota che viene prima di tutto creata una tabella temporanea che contiene il risultato completo della query, a questa viene applicata un piccolo indice con il campo:
ID int not null IDENTITY(1,1)
Ogni IDPersona valorizzato caricherà un valore anche per ID, questo dato rappresentarà il nostro indice per la gestione dei cursori, successivamente utilizzando il parametro @start e @rpp possiamo mettere in join le due tabelle e caricare "unicamente" i dati necesari per l'impaginazione di una singola pagina.
Commenti recenti