Share via


Execução preparada ODBC

A execução preparada é uma forma eficiente de executar uma instrução mais de uma vez. A instrução é primeiro compilada, ou preparada, em um plano de acesso. O plano de acesso é então executado uma ou mais vezes posteriormente. Para obter mais informações sobre planos de acesso, confira Processar uma instrução SQL.

A execução preparada geralmente é usada por meio de aplicativos verticais e personalizados para executar a mesma instrução SQL com parâmetros várias vezes. Por exemplo, o código a seguir prepara uma instrução para atualizar os preços de diferentes partes. Em seguida, ele executa a instrução várias vezes com valores de parâmetro diferentes 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 que a direta para instruções executadas mais de uma vez, primariamente, pois a instrução é compilada somente uma vez; instruções executadas diretamente são compiladas sempre que ocorrem. A execução preparada também pode fornecer uma redução no tráfego de rede, pois o driver pode enviar um identificador de plano de acesso à fonte de dados sempre que a instrução for executada, em vez de uma instrução SQL inteira, se a fonte de dados suportar identificadores de plano de acesso.

O aplicativo pode recuperar os metadados do conjunto de resultados depois que a instrução é preparada e antes de ela ser executada. No entanto, retornar metadados para instruções preparadas e não executadas é caro para alguns drivers e deve ser evitado por aplicativos interoperáveis, se possível. Para obter mais informações, confira Metadados de conjunto de resultados.

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

Importante

Confirmar ou reverter uma transação, chamando explicitamente SQLEndTran ou funcionando no modo de confirmação automática, faz com que algumas fontes de dados excluam os planos de acesso para todas as instruções em uma conexão. Para obter mais informações, confira 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, o aplicativo:

  1. Chama SQLPrepare e passa uma cadeia de caracteres contendo a instrução SQL.

  2. Define os valores de parâmetros. Os parâmetros podem realmente ser definidos antes ou depois de preparar a instrução. Para obter mais informações, confira Parâmetros de instrução mais adiante nesta seção.

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

  4. Repete as etapas 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. Isso inclui substituir as sequências de escape discutidas em Sequências de escape no ODBC. O aplicativo pode recuperar a forma modificada de uma instrução SQL chamando SQLNativeSql. As sequências de escape não serão substituídas se o atributo de instrução SQL_ATTR_NOSCAN estiver definido.

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

    • Armazena o identificador do plano de acesso retornado para execução posterior (se a preparação tiver sido bem-sucedida) ou retorna um erro (se a preparação falhar). 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 exibição não encontrada).

      Observação

      Alguns drivers não retornam erros neste ponto, mas os retornam quando a instrução é executada ou quando as funções de catálogo são chamadas. Assim, SQLPrepare pode parecer ter sido bem-sucedido quando, na verdade, falhou.

  6. Quando SQLExecute é chamado, o driver:

    • Recupera os valores atuais de parâmetro e os converte conforme necessário. Para obter mais informações, confira Parâmetros de instrução mais adiante nesta seção.

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

    • Retorna um erro. Geralmente, são erros em tempo de execução, como SQLSTATE 24000 (estado inválido do cursor). No entanto, alguns drivers retornam erros sintáticos e semânticos neste ponto.

Se a fonte de dados não oferecer suporte à preparação de instrução, o driver deverá emulá-la na medida do possível. Por exemplo, o driver pode não fazer nada quando SQLPrepare é chamado e, em seguida, executar a execução direta da instrução quando SQLExecute é chamado.

Se a fonte de dados oferecer suporte à verificação de sintaxe sem execução, o driver poderá enviar a instrução para verificação quando SQLPrepare for chamado e enviar a instrução para execução quando SQLExecute for chamado.

Se o driver não puder emular a preparação da instrução, ele armazenará a instrução quando SQLPrepare for chamado e a enviará para execução quando SQLExecute for chamado.

Como a preparação de instrução emulada não é perfeita, SQLExecute pode retornar erros normalmente retornados por SQLPrepare.