SQL Server não terminar a execução de um lote grande de instruções SQL

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 827575
Sintomas
Quando você executar um lote grande de instruções SQL que retorne vários conjuntos de resultados, Microsoft SQL Server pode parar de processar o lote antes de todas as instruções no lote são executadas. Os efeitos desse comportamento dependem de quais operações o lote executam instruções. Por exemplo, se o lote inicia uma transação no início e confirma a transação no final, a confirmação não pode ocorrer. Esse comportamento faz com que bloqueios a ser mantido mais do que o esperado. Isso também pode causar a transação ser partilhado quando a conexão é fechada. Se o lote não iniciar uma transação, os sintomas do problema podem ser que algumas instruções não são executadas.
Causa
Ao processar os resultados de um lote, o SQL Server preenche o buffer de saída da conexão com os conjuntos de resultado são criados pelo lote. Esses conjuntos de resultados devem ser processados pelo aplicativo cliente. Se você está executando um lote grande com vários conjuntos de resultados, preenchimentos de SQL Server que buffer de saída até que ele atinge um limite interno e não pode continuar a processar mais conjuntos de resultados. Nesse ponto, o controle retorna para o cliente. Quando o cliente começa a consumir os conjuntos de resultados, o SQL Server começa a executar o lote novamente porque agora há memória disponível no buffer de saída.
Como Contornar
Para contornar o problema, use um dos seguintes métodos:
  • método 1 : liberar todos os conjuntos de resultados de saída. Assim que todos os conjuntos de resultados de saída são consumidos pelo cliente, SQL Server conclui a execução do lote.
    • Se você estiver usando o Microsoft ODBC (Open Database Connectivity) para conectar-se ao SQL Server, você pode chamar o método SQLMoreResults até que o método relatórios que não há não mais conjuntos de resultados.
    • Se você estiver usando o Microsoft OLE DB para conectar-se ao SQL Server, você pode chamar repetidamente o método IMultipleResults::GetResult até que ele retorne DB_S_NORESULT.
  • método 2 : adicionar a instrução SET NOCOUNT ON para o início do lote. Se o lote é executado dentro de um procedimento armazenado, adicione a instrução ao início da definição do procedimento armazenado. Isso impede que SQL Server retornar vários tipos de conjuntos de resultados. Portanto, ele pode reduzir os dados a serem saída para o buffer de saída do servidor. No entanto, isso não garante que o problema não ocorrerá. Ela apenas aumenta a chance de que os dados que são retornados do servidor são pequenos o suficiente para caber em um lote de conjuntos de resultados.
anotações
  • A Microsoft recomenda que você sempre consumir todos os conjuntos de resultados do SQL Server independentemente do tamanho do lote que você está executando. Se você não liberar esses dados e há conjuntos de resultado com êxito a ser retornado à frente do erro no lote de conjunto de resultados, o cliente não pode descobrir os erros do servidor.
  • Aplicativos cliente devem liberar os conjuntos de resultados para garantir a correta execução.
Situação
Esse comportamento é por design.
Mais Informações

Etapas para reproduzir o problema

  1. Crie um procedimento armazenado SQL no banco de dados pubs com um lote relativamente grande do banco de dados de instruções de consulta. Você pode criar um procedimento que é semelhante à seguinte.

    Observação Substitua o texto "..." as instruções de consulta de banco de dados apropriado que são semelhantes de outras instruções de consulta de banco de dados no código.
    create proc bigBatch asbegin transaction	update authors set au_fname = 'newname1' where au_id='172-32-1176'	update authors set au_fname = 'newname2' where au_id='172-32-1176'	update authors set au_fname = 'newname3' where au_id='172-32-1176'	...	update authors set au_fname = 'newname1000' where au_id='172-32-1176'	commit transaction 
  2. Criar e configurar um nome de fonte de dados (DSN) com o banco de dados pubs que se conecta ao SQL Server.
  3. Inicie a ferramenta Profiler que está disponível com a instalação do Microsoft SQL Server.
  4. Criar e inicie um novo rastreamento para o SQL Server da ferramenta Profiler.

    Observação Certifique-se de adicionar a classe de evento é chamada de procedimento armazenado para o novo rastreamento SQL Profiler. Quando você fizer isso, você pode ver as etapas individuais no procedimento quando ele é executado.
  5. Conectar-se ao SQL Server usando ODBC. Para fazer isso, execute as seguintes etapas:
    1. Abra o exemplo de ferramenta de teste de ODBC está disponível com a instalação do Microsoft Data Access (MDAC) SDK.
    2. No menu conexão , clique em Conectar total .
    3. Na caixa de diálogo Conectar total , clique no nome da fonte de dados que você criou na etapa 2.
    4. Verifique se a conexão com o SQL Server é bem-sucedida.
    5. No menu Stmt , clique em SQLExecDirect .
    6. Na caixa StatementText , digite {chamar bigBatch} e, em seguida, clique em OK .
    Na análise de rastreamento SQL Profiler, você observe que o processamento do procedimento armazenado não é concluído. No entanto, a ferramenta de teste de ODBC indica que a execução foi bem-sucedida. Para todos os conjuntos de resultados de busca e para fazer com que o lote concluir no servidor, clique em Obter dados tudo no menu de resultados .

    Você pode se conectar ao SQL Server usando OLE. Para fazer isso, execute as seguintes etapas:
    1. Abra o exemplo de ferramenta do Microsoft OLE DB RowsetViewer está disponível com o SDK do MDAC.
    2. Conecte-se ao banco de dados de pubs do SQL Server usando a opção Conectar total .
    3. No menu comando , aponte para ICommand e, em seguida, clique em Executar .
    4. Na caixa de Texto de comando , digite {chamada bigBatch} .
    5. Clique em IID_IMultipleResults na lista REFIID e em seguida, clique em Propriedades .
    6. Na caixa de diálogo ICommandProperties::SetProperties , clique em DBPROP_IMultipleResults , altere o valor para VARIANT_TRUE e, em seguida, clique em OK .
    7. Clique em OK .
    Na análise de rastreamento SQL Profiler, você observe que o processamento do procedimento armazenado não é concluído. No entanto, a ferramenta RowsetViewer mostra que a operação foi bem-sucedida. Para recuperar todos os conjuntos de resultados, clica com o botão direito do objeto MultipleResults no painel esquerdo, aponte para IMultipleResults e, em seguida, clique em GetResult . Repita até que todos os conjuntos de resultados têm sido consumidos.

O problema é reproduzido mais facilmente quando estiver conectado ao SQL Server usando o protocolo pipes nome ou o protocolo de memória (LPC) compartilhado. Isso é devido o tamanho do buffer interno que o SQL Server tem disponível para os protocolos diferentes.

A seguir estão os possíveis efeitos desse problema. Os efeitos são variados e dependem exatamente o que o lote contém.
  • Considere que um lote de instruções de consulta de banco de dados é executado de um aplicativo. Se o lote de instruções de consulta de banco de dados é composto de um "BEGIN TRANSACTION" no início e "COMMIT TRANSACTION" no final, a operação de confirmação não pode ocorrer mesmo que o controle é retornado para o aplicativo. Isso é um problema porque os bloqueios mantidos possivelmente podem causar uma transação pendente e podem permanecer despercebidos.

    Nesse cenário, porque a transação é confirmada nunca em lote, ele permanece pendente e é revertido na desconexão do SQL Server.
  • Se você usar uma interface de programa aplicativo (API) para iniciar e confirmar sua transação, você pode ver o seguinte comportamento:
    • Se você usar a API para enviar uma notificação ao servidor para iniciar uma transação e, em seguida, você executar o lote, SQL pode processar apenas uma parte do lote e retornar o controle para o aplicativo.
    • Após esta etapa, se você usar a API para confirmar a transação, apenas a parte do lote foi processado é confirmada. Não ocorre nenhum erro.

      Por exemplo, com ODBC você chamar SQLSetConnectAttr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF) para iniciar a transação, e use SQLEndTran(SQL_COMMIT) para confirmar a transação.
Referências
Para obter informações adicionais sobre os comandos que geram vários resultados, visite o seguinte da MSDN (Microsoft Developer):Para obter informações adicionais sobre como ao processo de conjuntos de resultados múltiplos no OLE, visite o site da MSDN seguinte: Observação Se você estiver usando o ADO, chamar o método NextRecordset do objeto Recordset faz com que o provedor OLE DB executar o método IMultipleResults::GetResult .

Para obter informações adicionais sobre como processar vários resultados em ODBC, visite o seguinte site da MSDN:Para obter informações adicionais sobre a consulta execução instrução SET NOCOUNT, visite o seguinte site da MSDN:Para obter mais informações sobre ODBC SQLMoreResults API, visite o seguinte site da MSDN:Para obter mais informações sobre o método GetResult da interface OLE IMultipleResults , visite o seguinte site da MSDN:

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 827575 - Última Revisão: 04/19/2007 03:20:46 - Revisão: 4.8

Microsoft SQL Server 2000 Standard Edition, Microsoft ODBC Driver para Microsoft SQL Server 3.7, Microsoft OLE DB Provider for SQL Server, Microsoft SQL Server 2005 Enterprise Edition, Microsoft SQL Server 2005 Developer Edition, Microsoft SQL Server 2005 Standard Edition, Microsoft SQL Server 2005 Workgroup Edition

  • kbmt kbprb KB827575 KbMtpt
Comentários