Compartilhar via


Execução preparada

A API do ODBC define a execução preparada como um modo de reduzir a sobrecarga de análise e compilação associada à execução repetida da instrução Transact-SQL. O aplicativo compila uma cadeia de caracteres que contém uma instrução SQL e então a executa em duas fases. Ele chama SQLPrepare uma vez para que a instrução seja analisada e compilada no plano de execução pelo Mecanismo de Banco de Dados. Em seguida, chama SQLExecute para cada execução do plano de execução preparado. Dessa forma, a sobrecarga de análise e compilação é salva em cada execução. A execução preparada geralmente é usada através de aplicativos para executar a mesma instrução SQL com parâmetros várias vezes.

Para a maioria dos bancos de dados, a execução preparada é mais rápida que a direta para instruções executadas mais de três ou quatro vezes primariamente, pois a instrução é compilada somente uma vez, enquanto 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 do plano de execução e os valores de parâmetro, em vez de toda uma instrução SQL, para a fonte de dados sempre que a instrução for executada.

O SQL Server 2000 e posteriores reduzem a diferença de desempenho entre a execução preparada e a direta por meio de algoritmos aprimorados para detectar e reutilizar planos de execução de SQLExecDirect. Isso torna alguns dos benefícios de desempenho da execução preparada disponíveis para instruções executadas diretamente. Para obter mais informações, consulte Execução direta.

O SQL Server 2000 e posterior também oferece suporte nativo para execução preparada. Um plano de execução é criado em SQLPrepare e depois executado quando SQLExecute é chamado. Como o SQL Server 2000 e posteriores não são necessários para criar procedimentos armazenados temporários no SQLPrepare, não existe sobrecarga extra nas tabelas do sistema em tempdb.

Por motivos de desempenho, a preparação da instrução é adiada até que SQLExecute seja chamado ou uma operação de metapropriedade (como SQLDescribeCol ou SQLDescribeParam no ODBC) seja realizada. Esse é o comportamento padrão. Não são conhecidos erros na instrução que está sendo preparada até que ela seja executada ou uma operação de metapropriedade seja executada. Definir o atributo da instrução específica do driver ODBC do SQL Server Native Client SQL_SOPT_SS_DEFER_PREPARE como SQL_DP_OFF pode desativar esse comportamento padrão.

No caso de adiamento da preparação, chamar SQLDescribeCol ou SQLDescribeParam antes de chamar SQLExecute gera uma viagem de ida e volta extra ao servidor. Em SQLDescribeCol, o driver remove a cláusula WHERE da consulta e a envia ao servidor com SET FMTONLY ON para obter a descrição das colunas no primeiro conjunto de resultados retornado pela consulta. Em SQLDescribeParam, o driver chama o servidor para obter uma descrição das expressões ou colunas referenciadas por qualquer marcador de parâmetro na consulta. Esse método também tem algumas restrições, como não poder resolver parâmetros em subconsultas.

O uso excessivo de SQLPrepare com o driver ODBC do SQL Server Native Client degrada desempenho, principalmente quando conectado a versões anteriores do SQL Server. A execução preparada não deve ser usada para instruções executadas uma única vez. A execução preparada é mais lenta que a direta para uma única execução de instrução, pois ela requer uma viagem de ida e volta extra do cliente ao servidor. Em versões anteriores do SQL Server, ela também gera um procedimento armazenado temporário.

As instruções preparadas não podem ser usadas para criar objetos temporários no SQL Server 2000 ou posterior ou em versões anteriores do SQL Server, caso a opção de gerar procedimentos armazenados esteja ativa. Com esta opção ativada, a instrução preparada é criada em um procedimento armazenado temporário que é executado quando SQLExecute é chamado. Qualquer objeto temporário criado durante a execução de um procedimento armazenado é descartado automaticamente quando o procedimento for concluído. Qualquer um dos exemplos a seguir resulta na não criação da tabela temporária #sometable, se a opção de gerar procedimentos armazenados para preparação estiver ativa:

SQLPrepare(hstmt,
   "CREATE TABLE #sometable(cola int, colb char(8))",
   SQL_NTS);
SQLExecute(hstmt);

ou

SQLPrepare(hstmt,
   "SELECT * FROM Authors INTO #sometable",
   SQL_NTS);
SQLExecute(hstmt);

Alguns aplicativos de ODBC anteriores usavam SQLPreparesempre que SQLBindParameter era usado. SQLBindParameter não requer o uso de SQLPrepare, ele pode ser usado com SQLExecDirect. Por exemplo, use SQLExecDirect com SQLBindParameter para recuperar o código de retorno ou os parâmetros de saída de um procedimento armazenado executado só uma vez. Não use SQLPrepare com SQLBindParameter, a menos que a mesma instrução seja executada várias vezes.

Consulte também

Conceitos