CORRECÇÃO: uma instrução MERGE não pode impor uma restrição de chave externa quando a instrução atualiza uma coluna de chave exclusiva que não é parte de uma chave de cluster e há uma única linha como fonte de atualização no SQL Server 2008

Traduções deste artigo Traduções deste artigo
ID do artigo: 956718 - Exibir os produtos aos quais esse artigo se aplica.
Bug #: 50003167 (Hotfix do SQL)
Para obter mais informações sobre a lista mestra de compilações lançados após o lançamento do SQL, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
957826Onde você pode encontrar mais informações sobre o SQL Server 2008 compilações que foram lançados após o SQL Server 2008 e o SQL Server 2005 cria lançados após o SQL Server 2005 Service Pack 2
Expandir tudo | Recolher tudo

Sintomas

Em Microsoft SQL Server 2008, uma restrição de chave externa não pode ser imposta quando as seguintes condições forem verdadeiras:
  • Uma instrução MERGE é emitida.
  • A coluna de destino da atualização tem um índice exclusivo que não estão em cluster.
Considere o seguinte cenário. A instrução atualiza uma coluna exclusiva que é chamada Column1 de uma tabela chamada Table1. Table1 é mencionado por uma restrição de chave externa de uma tabela é denominada Table2.

O resultado é que linhas na Table1 são alteradas quando eles não devem ter sido. Além disso, Table2 terá linhas que possuem dangling referências a Table1.

Esse problema ocorre para esse cenário quando as seguintes condições forem verdadeiras:
  • A coluna Column1 referenciada na Table1 não é parte da chave do cluster de Table1.
  • Apenas um valor possível pode ser atribuído para a coluna Column1. Por exemplo, uma das seguintes situações ocorrerá:
    • A fonte de mala direta é uma única linha de dados. Por exemplo, a fonte de mala direta é de uma das instruções a seguir selecionadas:
      • select <ConstantValues>
      • select <Parameters>
      Observação Esse cenário é o cenário mais provável.
    • A fonte de mala direta é realmente uma única linha de dados. Por exemplo, a fonte de mala direta é de uma das instruções a seguir selecionadas:
      • select <ColumnName> from <TableName> where <TableName>.<ColumnName> = 1
        Observação <TableName>. <ColumnName> é conhecido pelo otimizador de consulta para ser um valor exclusivo.
      • select top 1 <ColumnName> from <TableName>
    • A associação entre a fonte de mala direta e o destino de mesclagem tem um predicado que garante que uma única linha será atualizada.
    • A cláusula de atualização define a coluna Column1 com um valor constante, independentemente da fonte de mala direta.
  • A opção Na atualização em cascata não está habilitada na restrição de chave externa em Table2.
Observação É recomendável que você aplique esse hotfix se você usar a instrução MERGE para atualizar colunas têm índices exclusivos que não estão em cluster que são referenciadas por restrições de chave externa.

Resolução

A correção para esse problema foi lançada primeiro em atualização cumulativa 1. Para obter mais informações sobre como obter esse pacote de atualizações cumulativas para o SQL Server 2008, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
956717Pacote de atualizações cumulativas 1 para SQL Server 2008
Observação Como as compilações são cumulativas, cada novo lançamento de correções contém todos os hotfixes e todas as correções segurança que foram incluídas com o SQL Server 2008 anteriores corrigir lançamento. Recomendamos que você considere a aplicação a versão de correção mais recente que contém esse hotfix. Para obter mais informações, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
956909O SQL Server 2008 compilações que lançadas foram após o lançamento SQL Server 2008 foi lançado

Como Contornar

O pacote de hotfix elimina o problema. Se você usar a instrução MERGE na situação descrita na seção "Sintomas" e se você optar por não aplicar o hotfix, siga estas etapas para eliminar esse problema:
  1. Reescreva a instrução MERGE para que sejam os valores para a fonte de mesclagem em uma tabela, uma tabela temporária ou uma variável de tabela em vez de ser in-alinhados na consulta.
  2. Use o sinalizador de rastreamento 8790. O sinalizador de traço força o otimizador para usar um tipo de plano que é chamado de um plano de atualização grande. Planos de atualização grande não tem o problema. Esta etapa apresenta riscos de desempenho para todas as instruções DML. Portanto, você deve evitar usar esta etapa, a menos que seja impossível alterar o aplicativo.
O script do Transact-SQL a seguir mostra uma maneira para alterar o script para resolver esse problema se você não pode aplicar esse hotfix.

Por exemplo, você tem um script semelhante à seguinte:
use tempdb;

drop table sale, product;
create table product(pno int not null primary key, name char(30), pAlternateKey char(6) not null unique);
create table sale(sno int not null primary key, pAlternateKey char(6) not null references product(pAlternateKey));
insert product values(1, 'Office Chair', 'ochair');
insert sale values(1, 'ochair')

-- No violation of foreign key constraint is detected. However, one should be.
merge into product
using (select 'Office Chair2' as name, 1 as pno, 'oxx' as pAlternateKey) as src
on product.pno = src.pno
when matched then
   update set product.pAlternateKey = src.pAlternateKey, 
              product.name = src.name
when not matched then
   insert values(src.pno, src.name, src.pAlternateKey);
alterar o script para que ele semelhante à seguinte:
insert product values(1, 'Office Chair', 'ochair');
insert sale values(1, 'ochair')
-- A foreign key constraint violation is detected, and the update fails.
declare @source table 
   (name nchar(30), pno int, pAlternateKey nchar(30));
insert into @source values('Office Chair2',1,'oxx');

merge into product
using @source as src
on product.pno = src.pno
when matched then
   update set product.pAlternateKey = src.pAlternateKey, 
              product.name = src.name
when not matched then
   insert values(src.pno, src.name, src.pAlternateKey);

Situação

A Microsoft confirmou que este é um problema nos produtos da Microsoft listados na seção "Aplica-se a".

Mais Informações

Para mais informações sobre quais arquivos são alterados e para obter informações sobre quaisquer pré-requisitos para aplicar o pacote de atualização cumulativa que contém o hotfix descrito neste artigo, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
956717Pacote de atualizações cumulativas 1 para SQL Server 2008

Referências

Para obter mais informações sobre a lista de compilações disponibilizadas após o lançamento do SQL Server 2008, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
956909O SQL Server 2008 compilações que lançadas foram após o lançamento SQL Server 2008 foi lançado


Para obter mais informações sobre o modelo incremental de serviços para o SQL Server, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
935897Há um modelo incremental de serviços da equipe do SQL Server para fornecer hotfixes para problemas relatados


Para obter mais informações sobre o esquema para nomeação para atualizações do SQL Server, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
822499Novo esquema para nomeação para pacotes de atualização de software do Microsoft SQL Server


Para obter mais informações sobre terminologia de atualização de software, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
824684Descrição da terminologia padrão que é usada para descrever as atualizações de software

Referências

Para obter mais informações sobre os índices que não estão em cluster no SQL Server 2008, visite o seguinte site da Web Microsoft Developer Network (MSDN):
http://msdn.microsoft.com/en-us/library/ms179325(SQL.100).aspx

Propriedades

ID do artigo: 956718 - Última revisão: sexta-feira, 19 de setembro de 2008 - Revisão: 4.0
A informação contida neste artigo aplica-se a:
  • Microsoft SQL Server 2008 Enterprise
  • Microsoft SQL Server 2008 Developer
  • Microsoft SQL Server 2008 Standard
  • Microsoft SQL Server 2008 Standard Edition for Small Business
  • Microsoft SQL Server 2008 Web
  • Microsoft SQL Server 2008 Workgroup
  • Microsoft SQL Server 2008 Express
  • Microsoft SQL Server 2008 Express with Advanced Services
Palavras-chave: 
kbmt kbautohotfix kbhotfixserver kbqfe kbpubtypekc kbfix KB956718 KbMtpt
Tradução automática
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: 956718

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com