Partilhar via


Execução preparada ODBC

A execução preparada é uma forma eficiente de executar uma instrução mais do que uma vez. A declaração é primeiro compilada, ou preparada, num plano de acesso. O plano de acesso é então executado uma ou mais vezes posteriormente. Para mais informações sobre planos de acesso, consulte Processamento de uma Instrução SQL.

A execução preparada é comumente usada por aplicações verticais e personalizadas para executar repetidamente a mesma instrução SQL parametrizada. Por exemplo, o código seguinte prepara uma declaração para atualizar os preços das diferentes peças. Depois, executa a instrução várias vezes com valores de parâmetro diferentes a cada vez.

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);  
}  

A execução preparada é mais rápida do que a execução direta para instruções executadas mais do que uma vez, principalmente porque a instrução é compilada apenas uma vez; As instruções executadas diretamente são compiladas cada vez que são executadas. A execução preparada também pode proporcionar uma redução no tráfego de rede, pois o driver pode enviar um identificador de plano de acesso para a fonte de dados cada vez que a instrução é executada, em vez de uma instrução SQL completa, se a fonte de dados suportar identificadores de plano de acesso.

A aplicação pode recuperar os metadados do conjunto de resultados depois de a instrução ser preparada e antes de ser executada. No entanto, devolver metadados para instruções preparadas e não executadas é dispendioso para alguns drivers e deve ser evitado por aplicações interoperáveis, se possível. Para mais informações, consulte Metadados do Conjunto de Resultados.

A execução preparada não deve ser usada para declarações executadas uma única vez. Para tais instruções, é ligeiramente mais lento do que a execução direta porque requer uma chamada adicional de função ODBC.

Importante

Confirmar ou reverter uma transação, seja chamando explicitamente SQLEndTran ou trabalhando em modo de auto-commit, faz com que algumas fontes de dados eliminem os planos de acesso de todas as instruções numa ligação. Para mais informações, consulte as opções SQL_CURSOR_COMMIT_BEHAVIOR e SQL_CURSOR_ROLLBACK_BEHAVIOR na descrição da função SQLGetInfo .

Para preparar e executar uma instrução, a aplicação:

  1. Chama o SQLPrepare e passa-lhe uma string contendo a instrução SQL.

  2. Define os valores de quaisquer parâmetros. Os parâmetros podem, na verdade, ser definidos antes ou depois de preparar a declaração. Para mais informações, consulte Parâmetros da Instrução, mais à frente nesta secção.

  3. Chama SQLExecute e faz qualquer processamento adicional necessário, como buscar dados.

  4. Repete os passos 2 e 3 conforme necessário.

  5. Quando SQLPrepare é chamado, o driver:

    • Modifica a instrução SQL para usar a gramática SQL da fonte de dados sem analisar a instrução. Isto inclui substituir as sequências de escape discutidas em Escape Sequences in ODBC. A aplicação pode recuperar a forma modificada de uma instrução SQL chamando SQLNativeSql. As sequências de escape não são substituídas se o atributo da instrução SQL_ATTR_NOSCAN estiver definido.

    • Envia a declaração para a fonte de dados para preparação.

    • Armazena o identificador do plano de acesso devolvido para execução posterior (caso a preparação tenha sido bem-sucedida) ou devolve quaisquer erros (caso a preparação tenha falhado). Os erros incluem erros sintáticos como SQLSTATE 42000 (Erro de sintaxe ou violação de acesso) e erros semânticos como SQLSTATE 42S02 (Tabela base ou vista não encontrada).

      Observação

      Alguns drivers não devolvem erros neste ponto, mas sim quando a instrução é executada ou quando são chamadas funções de catálogo. Assim, o SQLPrepare pode parecer ter tido sucesso quando, na verdade, falhou.

  6. Quando SQLExecute é chamado, o driver:

    • Recupera os valores atuais dos parâmetros e converte-os conforme necessário. Para mais informações, consulte Parâmetros da Instrução, mais adiante nesta secção.

    • Envia o identificador do plano de acesso e os valores convertidos dos parâmetros para a fonte de dados.

    • Devolve quaisquer erros. Estes são geralmente erros em tempo de execução, como SQLSTATE 24000 (estado do cursor inválido). No entanto, alguns drivers devolvem erros sintáticos e semânticos neste ponto.

Se a fonte de dados não suportar a preparação de declarações, o driver deve emulá-la na medida do possível. Por exemplo, o driver pode não fazer nada quando o SQLPrepare é chamado e depois executar diretamente a instrução quando o SQLExecute é chamado.

Se a fonte de dados suportar verificação de sintaxe sem execução, o driver pode submeter a instrução para verificação quando o SQLPrepare é chamado e submeter a instrução para execução quando o SQLExecute for chamado.

Se o driver não conseguir emular a preparação da instrução, armazena a instrução quando o SQLPrepare é chamado e submete-o para execução quando o SQLExecute é chamado.

Como a preparação de instruções emuladas não é perfeita, o SQLExecute pode devolver quaisquer erros normalmente devolvidos pelo SQLPrepare.