Un cursor de base de dades és un mecanisme que permet recórrer les files d’un conjunt de resultats retornat per una consulta a una base de dades. A més de facilitar aquest recorregut, un cursor permet processar les dades de manera progressiva i, en determinats casos, identificar la fila actual per actualitzar-la o suprimir-la. Per aquesta capacitat de desplaçament sobre una seqüència de registres, el cursor és comparable a un iterador en programació.

Els cursors s’utilitzen principalment quan una aplicació o un procediment necessita tractar les files d’un resultat de manera seqüencial, una a una o en petits blocs, en lloc de treballar sempre amb tot el conjunt de resultats alhora. Aquesta tècnica és especialment útil quan una consulta retorna moltes files, ja que permet recuperar-les de manera progressiva i limitar el consum de memòria.

Funcionament En SQL, l’ús d’un cursor segueix habitualment un model bàsic format per quatre operacions: declarar-lo, obrir-lo, recuperar-ne les files i tancar-lo. En primer lloc, el cursor es declara i s’associa a una consulta. Després, s’obre per establir el conjunt de resultats. A continuació, les files es recuperen successivament mitjançant una operació de lectura. Finalment, el cursor es tanca per alliberar els recursos associats.

En PostgreSQL, la sentència DECLARE defineix un cursor i l’associa a una consulta, mentre que les files s’obtenen posteriorment mitjançant FETCH. Els cursors permeten encapsular una consulta i recuperar-ne un nombre reduït de files cada vegada, en lloc d’obtenir tot el resultat de cop.

Just després d’obrir-se correctament, el cursor queda situat abans de la primera fila del conjunt de resultats. Cada operació de recuperació n’altera la posició, i quan ja no queden més files disponibles el sistema indica el final del conjunt de resultats.

Cursors desplaçables Els cursors es poden classificar segons la seva capacitat de desplaçament. Un cursor de només avanç (forward-only) només permet recuperar cada fila una sola vegada i avançar successivament cap a la següent. En canvi, un cursor desplaçable (scrollable cursor) permet moure’s a diverses posicions del conjunt de resultats, com ara la fila següent, l’anterior, la primera, l’última o una posició absoluta o relativa.

En PostgreSQL, l’opció SCROLL indica que el cursor pot recuperar files de manera no seqüencial, mentre que NO SCROLL n’impedeix els desplaçaments cap enrere. Els cursors desplaçables poden tenir un cost de rendiment superior, i els desplaçaments enrere poden donar resultats inesperats en consultes amb funcions volàtils.

Cursors amb retenció Els cursors se solen tancar automàticament en finalitzar una transacció. Aquest comportament es pot modificar amb la clàusula WITH HOLD, que permet que el cursor continuï disponible després d’un COMMIT. Si no s’especifica aquesta opció, el comportament per defecte és WITHOUT HOLD.

En PostgreSQL, els cursors creats amb WITH HOLD romanen accessibles en transaccions posteriors dins de la mateixa sessió, però es tanquen quan la sessió acaba o quan es fa un CLOSE explícit. En la implementació actual del sistema, les files d’un cursor amb retenció es poden copiar a memòria temporal o a un fitxer temporal perquè continuïn disponibles després del COMMIT.

Actualització i supressió posicionades A més de recuperar dades, un cursor pot servir per identificar la fila actual d’un conjunt de resultats amb la finalitat d’actualitzar-la o suprimir-la. L’estàndard SQL defineix per a aquest propòsit les instruccions d’actualització posicionada i supressió posicionada, que fan referència a la fila actual mitjançant l’expressió WHERE CURRENT OF en lloc d’una clàusula WHERE basada en predicats ordinaris.

En PostgreSQL, es recomana utilitzar FOR UPDATE quan el cursor s’hagi d’emprar amb UPDATE ... WHERE CURRENT OF o DELETE ... WHERE CURRENT OF, ja que això ajuda a evitar que altres sessions modifiquin les files entre el moment en què són recuperades i el moment en què són actualitzades o suprimides.

Inconvenients L’ús de cursors també presenta inconvenients. El tractament fila per fila pot resultar menys eficient que les operacions formulades sobre conjunts, que constitueixen una de les bases del model relacional. A més, la recuperació reiterada de files pot incrementar el cost de comunicació entre el client i el servidor i consumir recursos addicionals del sistema.

Els cursors també poden requerir memòria temporal, estructures internes i, en determinats casos, bloquejos. Si no es tanquen correctament, aquests recursos poden romandre ocupats fins que es tanqui la sessió corresponent. Per aquest motiu, en moltes situacions es prefereixen les operacions basades en conjunts, i els cursors es reserven per a casos en què el processament seqüencial o incremental dels resultats és realment necessari.

Ús en programació asíncrona En entorns de programació asíncrona, els cursors són útils perquè permeten consumir conjunts de resultats grans de manera progressiva, sense necessitat de carregar-los íntegrament a la memòria en una sola operació. Aquesta característica és especialment rellevant en aplicacions que han de mantenir una bona capacitat de resposta mentre processen dades provinents d’una base de dades.

En Python, el concepte de cursor també apareix en les interfícies de connexió amb bases de dades. La documentació oficial del mòdul sqlite3 presenta l’objecte Cursor com l’element utilitzat per executar sentències SQL i recuperar resultats, mentre que l’especificació PEP 249 defineix el cursor com a part central de la Python Database API. En el context de biblioteques asíncrones de base de dades, aquest model permet mantenir el mateix principi general de recuperació progressiva de resultats.

Vegeu també SQL PostgreSQL Iterador Transacció (informàtica)

Referències

Categoria:Bases de dades