Esecuzione preparata ODBC

L'esecuzione preparata è un modo efficiente per eseguire un'istruzione più di una volta. Innanzitutto, l'istruzione viene compilata o preparata in un piano di accesso. In seguito, Il piano di accesso viene eseguito una o più volte. Per ulteriori informazioni sui piani di accesso, vedere Elaborare un'istruzione SQL.

L'esecuzione preparata viene generalmente utilizzata dalle applicazioni verticali e personalizzate per eseguire ripetutamente la stessa istruzione SQL con parametri. Per esempio, il codice seguente prepara un'istruzione per aggiornare i prezzi di diverse parti. Dopodiché esegue l'istruzione più volte, ogni volta con valori di parametro diversi.

SQLREAL       Price;  
SQLUINTEGER   PartID;  
SQLINTEGER    PartIDInd = 0, PriceInd = 0;  
  
// Prepare a statement to update salaries in the Employees table.  
SQLPrepare(hstmt, "UPDATE Parts SET Price = ? WHERE PartID = ?", SQL_NTS);  
  
// Bind Price to the parameter for the Price column and PartID to  
// the parameter for the PartID column.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &Price, 0, &PriceInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 10, 0,  
                  &PartID, 0, &PartIDInd);  
  
// Repeatedly execute the statement.  
while (GetPrice(&PartID, &Price)) {  
   SQLExecute(hstmt);  
}  

L'esecuzione preparata è più veloce dell'esecuzione diretta per le istruzioni eseguite più di una volta, soprattutto perché l'istruzione viene compilata una volta sola, mentre le istruzioni eseguite direttamente vengono compilate ogni volta che vengono eseguite. L'esecuzione preparata, inoltre, può offrire una riduzione del traffico di rete perché il driver può inviare all'origine dati un identificatore del piano di accesso, anziché un'intera istruzione SQL, ogni volta che viene eseguita l'istruzione se l’origine dati supporta gli identificatori del piano di accesso.

L'applicazione può recuperare i metadati per il set di risultati dopo che l’istruzione è stata preparata e prima della sua esecuzione. Tuttavia, la restituzione di metadati per istruzioni preparate e non elaborate è costosa per alcuni driver ed è meglio che le applicazioni interoperabili la evitino il più possibile. Per ulteriori informazioni, vedere Set di risultati di metadati.

L'esecuzione preparata non dev’essere utilizzata per le istruzioni eseguite una sola volta. Per tali istruzioni, è leggermente più lenta rispetto all'esecuzione diretta perché richiede una chiamata di funzione ODBC aggiuntiva.

Importante

Eseguire il commit o il rollback di una transazione, sia chiamando in modo esplicito SQLEndTran sia utilizzando la modalità di commit automatico, causa l’eliminazione dei piani di accesso per tutte le istruzioni in una connessione da parte di alcune origine dati. Per ulteriori informazioni, vedere le opzioni SQL_CURSOR_COMMIT_BEHAVIOR e SQL_CURSOR_ROLLBACK_BEHAVIOR nella descrizione della funzione SQLGetInfo.

Per preparare ed eseguire un'istruzione, l'applicazione:

  1. Chiama SQLPrepare e lo passa a una stringa contenente l'istruzione SQL.

  2. Imposta i valori di qualsiasi parametro. In realtà, i parametri possono essere impostati sia prima che dopo la preparazione dell'istruzione. Per ulteriori informazioni, vedere Parametri d’istruzione, più avanti in questa sezione.

  3. Chiama SQLExecute ed esegue qualsiasi elaborazione aggiuntiva necessaria, come per esempio il recupero dei dati.

  4. Ripete i passaggi 2 e 3 in base alle esigenze.

  5. Quando viene chiamato SQLPrepare, il driver:

    • Modifica l'istruzione SQL per usare la grammatica SQL dell'origine dati senza analizzare l'istruzione. Questo include la sostituzione delle sequenze di escape descritte in Sequenze di escape in ODBC. L'applicazione può recuperare il modulo modificato di un'istruzione SQL chiamando SQLNativeSql. Le sequenze di escape non vengono sostituite se l'attributo dell'istruzione SQL_ATTR_NOSCAN è impostato;

    • Invia l'istruzione all'origine dati per la preparazione.

    • Archivia l'identificatore del piano di accesso restituito per un'esecuzione successiva (se la preparazione è riuscita) o restituisce eventuali errori (se la preparazione non è riuscita). Gli errori includono errori sintattici, come SQLSTATE 42000 (errore di sintassi o violazione di accesso) ed errori semantici, come SQLSTATE 42S02 (tabella di base o vista non trovata).

      Nota

      Alcuni driver non restituiscono errori in questa fase, ma li restituiscono invece quando viene eseguita l'istruzione o quando vengono chiamate le funzioni catalogo. Pertanto, potrebbe sembrare che SQLPrepare abbia un esito positivo quando in realtà non è riuscito.

  6. Quando viene chiamato SQLExecute, il driver:

    • Recupera i valori dei parametri correnti e li converte in base alle esigenze. Per ulteriori informazioni, vedere Parametri d’istruzione, più avanti in questa sezione.

    • Invia l'identificatore del piano di accesso e i valori dei parametri convertiti all'origine dati.

    • Restituisce gli errori. In genere, si tratta di errori di run-time, come SQLSTATE 24000 (stato cursore non valido). Tuttavia, in questa fase alcuni driver restituiscono errori sintattici e semantici.

Se l'origine dati non supporta la preparazione delle istruzioni, il driver deve emularla per quanto gli è possibile. Per esempio, il driver potrebbe non eseguire alcuna operazione quando viene chiamato SQLPrepare ed eseguire l'esecuzione diretta dell'istruzione in seguito, quando viene chiamato SQLExecute.

Se l'origine dati supporta il controllo della sintassi senza esecuzione, il driver potrebbe inviare l'istruzione per verificare quando viene chiamato SQLPrepare e inviare l'istruzione per l'esecuzione quando viene chiamato SQLExecute.

Se il driver non può emulare la preparazione dell'istruzione, archivia l'istruzione quando viene chiamato SQLPrepare e la invia per l'esecuzione quando viene chiamato SQLExecute.

Poiché la preparazione dell'istruzione emulata non è perfetta, SQLExecute può restituire eventuali errori normalmente restituiti da SQLPrepare.