Cursori dinamici ODBC

Un cursore dinamico è solo questo: dinamico. Può rilevare eventuali modifiche apportate all'appartenenza, all'ordine e ai valori del set di risultati dopo l'apertura del cursore. Si supponga, ad esempio, che un cursore dinamico recuperi due righe e un'altra applicazione aggiorni una di queste righe ed elimini l'altra. Se il cursore dinamico tenta di recuperare tali righe, non troverà la riga eliminata ma restituirà i nuovi valori per la riga aggiornata.

I cursori dinamici rilevano tutti gli aggiornamenti, le eliminazioni e gli inserimenti, sia quelli creati da altri utenti. È soggetto al livello di isolamento della transazione, impostato dall'attributo di connessione SQL_ATTR_TXN_ISOLATION. La matrice di stato della riga specificata dall'attributo dell'istruzione SQL_ATTR_ROW_STATUS_PTR riflette queste modifiche e può contenere SQL_ROW_SUCCESS, SQL_ROW_SUCCESS_WITH_INFO, SQL_ROW_ERROR, SQL_ROW_UPDATED e SQL_ROW_ADDED. Non può restituire SQL_ROW_DELETED perché un cursore dinamico non restituisce righe eliminate all'esterno del set di righe e pertanto non riconosce più l'esistenza della riga eliminata nel set di risultati o l'elemento corrispondente nella matrice di stato della riga. SQL_ROW_ADDED viene restituito solo quando una riga viene aggiornata da una chiamata a SQLSetPos, non quando viene aggiornata da un altro cursore.

Un modo per implementare cursori dinamici nel database consiste nel creare un indice selettivo che definisce l'appartenenza e l'ordinamento del set di risultati. Poiché l'indice viene aggiornato quando altri apportano modifiche, un cursore basato su tale indice è sensibile a tutte le modifiche. La selezione aggiuntiva all'interno del set di risultati definito da questo indice è possibile tramite l'elaborazione lungo l'indice.

I cursori dinamici possono essere simulati richiedendo l'ordinamento del set di risultati in base a una chiave univoca. Con tale restrizione, i recupero vengono eseguiti eseguendo un'istruzione SELECT ogni volta che il cursore recupera le righe. Si supponga, ad esempio, che il set di risultati sia definito da questa istruzione:

SELECT * FROM Customers ORDER BY Name, CustID  

Per recuperare il set di righe successivo in questo set di risultati, il cursore simulato imposta i parametri nell'istruzione SELECT seguente sui valori nell'ultima riga del set di righe corrente e quindi lo esegue:

SELECT * FROM Customers WHERE (Name > ?) AND (CustID > ?)  
   ORDER BY Name, CustID  

Questa istruzione crea un secondo set di risultati, il primo set di righe di cui è il set di righe successivo nel set di risultati originale, in questo caso il set di righe nella tabella Customers. Il cursore restituisce questo set di righe all'applicazione.

È interessante notare che un cursore dinamico implementato in questo modo crea effettivamente molti set di risultati, che consente di rilevare le modifiche al set di risultati originale. L'applicazione non apprende mai l'esistenza di questi set di risultati ausiliari; appare semplicemente come se il cursore sia in grado di rilevare le modifiche apportate al set di risultati originale.