CORRECÇÃO: Uma instrução MERGE poderá não impor uma restrição de chave externa quando a instrução actualiza uma única coluna de chave que não faz parte de uma chave de clusters e houver uma única linha como a origem de actualização do SQL Server 2008

Traduções de Artigos Traduções de Artigos
Artigo: 956718 - Ver produtos para os quais este artigo se aplica.
N.º de bugs: 50003167 (correcção SQL)
Para obter mais informações sobre a lista principal de compilações disponibilizadas após o lançamento do SQL, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
957826Onde pode encontrar mais informações sobre o SQL Server 2008 cria disponibilizadas depois do SQL Server 2008 e o SQL Server 2005 cria disponibilizadas depois do SQL Server 2005 Service Pack 2
Expandir tudo | Reduzir tudo

Sintomas

No SQL Server 2008, uma restrição de chave externa não pode ser aplicada quando se verificam as seguintes condições:
  • Uma instrução MERGE é emitida.
  • A coluna de destino da actualização tem um índice agrupado exclusivo.
Considere o seguinte cenário. A instrução actualiza uma coluna exclusiva que chama-se Column1 de uma tabela denominada Table1. Table1 é referenciado por uma restrição de chave externa de uma tabela com o nome Table2.

O resultado é que linhas Table1 são alteradas quando estas não devem ter sido. Além disso, Table2 terão linhas que têm referências dangling Table1.

Este problema ocorre neste cenário quando se verificam as seguintes condições:
  • A coluna referenciada Column1Table1 não faz parte da chave clustering do Table1.
  • Apenas um valor possível pode ser atribuído à coluna Column1. Por exemplo, ocorre uma das seguintes situações:
    • A origem de impressão em série é uma única linha de dados. Por exemplo, a origem de impressão em série é uma das seguintes instruções select:
      • select <ConstantValues>
      • select <Parameters>
      Nota Neste cenário é o cenário mais provável.
    • A origem de impressão em série é realmente uma única linha de dados. Por exemplo, a origem de impressão em série é uma das seguintes instruções select:
      • select <ColumnName> from <TableName> where <TableName>.<ColumnName> = 1
        Nota <TableName>. <ColumnName> é conhecida pelo optimizador de consultas para um valor exclusivo.
      • select top 1 <ColumnName> from <TableName>
    • A associação entre a origem de impressão em série e o destino de impressão em série tem um predicado que garante que uma única linha será actualizada.
    • A cláusula de actualização define a coluna Column1 para um valor constante, independentemente da origem de impressão em série.
  • A opção Na actualização em cascata não está activada na restrição de chave externa Table2.
Nota Recomendamos que aplique esta correcção se utilizar a instrução MERGE para actualizar as colunas que tenham agrupados índices exclusivos que são referenciados por restrições de chave externa.

Resolução

A correcção deste problema primeiro foi disponibilizada em 1 de actualização cumulativa. Para obter mais informações sobre como obter este pacote de actualização cumulativa para o SQL Server 2008, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
956717Pacote de actualização cumulativa 1 para o SQL Server 2008
Nota Uma vez que as compilações são cumulativas, cada nova versão de correcção contém todas as correcções e todas as correcções de segurança incluídas com o SQL Server 2008 anterior corrigir lançamento. Recomendamos que considere aplicar a versão de correcção mais recente que contenha esta correcção. Para obter mais informações, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
956909O SQL Server 2008 cria disponibilizadas após o lançamento do SQL Server 2008

Como contornar

O pacote de correcção elimina o problema. Se utilizar a instrução MERGE no cenário descrito na secção "Sintomas" e se optar por não aplicar a correcção, siga estes passos para resolver este problema:
  1. Voltar a escrever a instrução MERGE para que os valores para a origem de impressão em série numa tabela, tabela temporária ou variável tabela em vez de ser com in-linhas na consulta.
  2. Utilize o sinalizador de rastreamento 8790. Este sinalizador de rastreio força o optimizador para utilizar um tipo de plano que chama um plano de actualização grande. Planos de actualização largura não tem o problema. Este passo efectua riscos de desempenho para todas as instruções DML. Por este motivo, deve evitar utilizar este passo, a menos que seja impossível alterar a aplicação.
O seguinte script Transact-SQL mostra uma forma de alterar o script para resolver este problema se não é possível aplicar esta correcção.

Por exemplo, tiver 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 é semelhante ao 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);

Ponto Da Situação

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

Mais Informação

Para obter mais informações sobre os ficheiros que são alterados e para obter informações sobre quaisquer pré-requisitos para aplicar o pacote de actualização cumulativa que contém a correcção que é descrita neste artigo da base de dados de conhecimento da Microsoft, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
956717Pacote de actualização cumulativa 1 para o SQL Server 2008

Referências

Para obter mais informações sobre a lista de compilações disponíveis após o lançamento do SQL Server 2008, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
956909O SQL Server 2008 cria disponibilizadas após o lançamento do SQL Server 2008


Para obter mais informações sobre o modelo de assistência incremental para o SQL Server, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
935897Um modelo de assistência incremental está disponível a equipa do SQL Server para proporcionar correcções para problemas comunicados


Para obter mais informações sobre o esquema de atribuição de nomes para as actualizações do SQL Server, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
822499Novo esquema de atribuição de nomes de ficheiros para pacotes de actualização de software do Microsoft SQL Server


Para obter mais informações sobre a terminologia de actualização de software, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
824684Descrição da terminologia padrão utilizada para descrever actualizações de software da Microsoft

Referências

Para mais informações acerca dos índices agrupados do SQL Server 2008, visite o seguinte Web site da Microsoft Developer Network (MSDN):
http://msdn.microsoft.com/en-us/library/ms179325(SQL.100).aspx

Propriedades

Artigo: 956718 - Última revisão: 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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