Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Se l'origine dati non supporta istruzioni di aggiornamento ed eliminazione posizionate, il driver può simulare queste istruzioni. Ad esempio, la libreria di cursori ODBC simula le istruzioni di aggiornamento ed eliminazione posizionate. La strategia generale per simulare istruzioni posizionate di aggiornamento ed eliminazione consiste nel convertire le istruzioni posizionate in istruzioni con ricerca. Questa operazione viene eseguita sostituendo la clausola WHERE CURRENT OF con una clausola WHERE cercata che identifica la riga corrente.
Ad esempio, poiché la colonna CustID identifica in modo univoco ogni riga nella tabella Customers, l'istruzione DELETE posizionata
DELETE FROM Customers WHERE CURRENT OF CustCursor
potrebbe essere convertito in
DELETE FROM Customers WHERE (CustID = ?)
Il driver può usare uno degli identificatori di riga seguenti nella clausola WHERE :
Colonne i cui valori servono per identificare in modo univoco ogni riga della tabella. Ad esempio, la chiamata a SQLSpecialColumns con SQL_BEST_ROWID restituisce la colonna o il set ottimale di colonne che servono a questo scopo.
Pseudo-colonne, fornite da alcune fonti di dati, allo scopo di identificare in modo univoco ogni riga. Possono anche essere recuperabili chiamando SQLSpecialColumns.
Indice univoco, se disponibile.
Tutte le colonne nel set di risultati.
Esattamente quali colonne un driver debba utilizzare nella clausola WHERE che viene costruita dipendono dal driver. In alcune origini dati, determinare un identificatore di riga può essere costoso. Tuttavia, è più veloce da eseguire e garantisce che un'istruzione simulata aggiorni o elimini al massimo una riga. A seconda delle funzionalità del sistema DBMS sottostante, l'uso di un identificatore di riga può essere costoso da configurare. Tuttavia, è più veloce da eseguire e garantisce che un'istruzione simulata aggiorni o elimini una sola riga. L'opzione di usare tutte le colonne nel set di risultati è in genere molto più semplice da configurare. Tuttavia, è più lento eseguire e, se le colonne non identificano in modo univoco una riga, possono comportare l'aggiornamento o l'eliminazione involontaria delle righe, soprattutto quando l'elenco di selezione per il set di risultati non contiene tutte le colonne presenti nella tabella sottostante.
A seconda di quale delle strategie precedenti supporta il driver, un'applicazione può scegliere quale strategia deve usare il driver con l'attributo di istruzione SQL_ATTR_SIMULATE_CURSOR. Anche se potrebbe sembrare strano che un'applicazione rischia di rischiare involontariamente l'aggiornamento o l'eliminazione di una riga, l'applicazione può rimuovere questo rischio assicurando che le colonne nel set di risultati identifichino in modo univoco ogni riga nel set di risultati. In questo modo, si risparmia al conducente lo sforzo di dover eseguire questa operazione.
Se il driver sceglie di usare un identificatore di riga, intercetta l'istruzione SELECT FOR UPDATE che crea il set di risultati. Se le colonne nell'elenco di selezione non identificano in modo efficace una riga, il driver aggiunge le colonne necessarie alla fine dell'elenco di selezione. Alcune origini dati hanno una singola colonna che identifica sempre in modo univoco una riga, ad esempio la colonna ROWID in Oracle; se tale colonna è disponibile, il driver lo usa. In caso contrario, il driver chiama SQLSpecialColumns per ogni tabella nella clausola FROM per recuperare un elenco delle colonne che identificano in modo univoco ogni riga. Una restrizione comune risultante da questa tecnica è che la simulazione del cursore ha esito negativo se nella clausola FROM sono presenti più tabelle.
Indipendentemente dal modo in cui il driver identifica le righe, in genere rimuove la clausola FOR UPDATE OF dall'istruzione SELECT FOR UPDATE prima di inviarla all'origine dati. La clausola FOR UPDATE OF viene usata solo con istruzioni di aggiornamento ed eliminazione posizionate. In genere, le origini dati che non supportano le istruzioni di aggiornamento ed eliminazione posizionate non le supportano affatto.
Quando l'applicazione invia un'istruzione di aggiornamento o eliminazione posizionata per l'esecuzione, il driver sostituisce la clausola WHERE CURRENT OF con una clausola WHERE contenente l'identificatore di riga. I valori di queste colonne vengono recuperati da una cache gestita dal driver per ogni colonna usata nella clausola WHERE . Dopo che il driver ha sostituito la clausola WHERE, invia l'istruzione all'origine dati per l'esecuzione.
Si supponga, ad esempio, che l'applicazione invii l'istruzione seguente per creare un set di risultati:
SELECT Name, Address, Phone FROM Customers FOR UPDATE OF Phone, Address
Se l'applicazione ha impostato SQL_ATTR_SIMULATE_CURSOR per richiedere una garanzia di univocità e se l'origine dati non fornisce una pseudo-colonna che identifica sempre in modo univoco una riga, il driver chiama SQLSpecialColumns per la tabella Customers, individua che CustID è la chiave della tabella Customers e lo aggiunge all'elenco di selezione, e esegue lo strip della clausola FOR UPDATE OF :
SELECT Name, Address, Phone, CustID FROM Customers
Se l'applicazione non ha richiesto una garanzia di univocità, il driver rimuove solo la clausola FOR UPDATE OF :
SELECT Name, Address, Phone FROM Customers
Si supponga che l'applicazione scorre il set di risultati e invii l'istruzione di aggiornamento posizionata seguente per l'esecuzione, dove Cust è il nome del cursore sul set di risultati:
UPDATE Customers SET Address = ?, Phone = ? WHERE CURRENT OF Cust
Se l'applicazione non ha richiesto una garanzia di univocità, il driver sostituisce la clausola WHERE e associa il parametro CustID alla variabile nella cache:
UPDATE Customers SET Address = ?, Phone = ? WHERE (CustID = ?)
Se l'applicazione non ha richiesto una garanzia di univocità, il driver sostituisce la clausola WHERE e associa i parametri Name, Address e Phone in questa clausola alle variabili nella cache:
UPDATE Customers SET Address = ?, Phone = ?
WHERE (Name = ?) AND (Address = ?) AND (Phone = ?)