REVISIÓN: Una instrucción MERGE puede exigir no una restricción foreign key en cuando la instrucción actualiza una columna de clave única que no es parte de una clave de agrupación y hay una sola fila como origen de actualización de SQL Server 2008

Seleccione idioma Seleccione idioma
Id. de artículo: 956718 - Ver los productos a los que se aplica este artículo
Nº de error: 50003167 (revisión SQL)
Para obtener más información acerca de la lista maestra de generaciones que se publicaron después del lanzamiento de SQL, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
957826Donde puede encontrar más información acerca de SQL Server 2008 generaciones que se publicaron después SQL Server 2008 y SQL Server 2005 genera que se publicaron después SQL Server 2005 Service Pack 2
Expandir todo | Contraer todo

Síntomas

En Microsoft SQL Server 2008, una restricción foreign key puede no aplicarse cuando se cumplen las condiciones siguientes:
  • Se emite una instrucción MERGE.
  • La columna de destino de la actualización tiene un índice único no agrupado.
Tenga en cuenta la situación siguiente. La instrucción actualiza una columna única que se denomina Column1 de una tabla denominada Table1. Table1 se hace referencia a una restricción foreign key de una tabla que se denomina Table2.

El resultado es que se modifican filas en Table1 al que no deberían haber sido. Además, Table2 tendrá filas que tienen referencias pendiente a Table1.

Este problema se produce para este escenario cuando se cumplen las condiciones siguientes:
  • La columna de Column1 al que se hace referencia en Table1 no forma parte de la clave de organización por clústeres de Table1.
  • Sólo un valor posible puede asignarse a la columna Column1. Por ejemplo, uno de los escenarios siguientes se produce:
    • El origen de combinación es una sola fila de datos. Por ejemplo, el origen de combinación es una de las siguientes instrucciones select:
      • select <ConstantValues>
      • select <Parameters>
      Nota Este escenario es el escenario más probable.
    • El origen de combinación es realmente una sola fila de datos. Por ejemplo, el origen de combinación es una de las siguientes instrucciones select:
      • select <ColumnName> from <TableName> where <TableName>.<ColumnName> = 1
        Nota <TableName>. <ColumnName> se sabe por el optimizador de consultas que ser un valor único.
      • select top 1 <ColumnName> from <TableName>
    • La combinación entre el origen de combinación y el destino de combinación tiene un predicado que garantiza que se actualizará una sola fila.
    • La cláusula de actualización establece la columna de Column1 en un valor constante, independientemente del origen de combinación.
  • La opción On Update Cascade no está habilitada en la restricción foreign key en Table2.
Nota Le recomendamos que aplique este hotfix si utiliza la instrucción MERGE para actualizar las columnas que tienen índices únicos no agrupados que hacen referencia las restricciones de clave externa.

Solución

La corrección para este problema se publicó por primera vez en la actualización acumulativa 1. Para obtener más información acerca de cómo obtener este paquete de actualización acumulativa para SQL Server 2008, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
956717Paquete de actualización acumulativa 1 de SQL Server 2008
Nota Como las compilaciones son acumulativas, cada versión de revisión nueva contiene todas las revisiones y revisión de todas las revisiones de seguridad incluidas con la anterior de SQL Server 2008. Recomendamos que considere aplicar la versión de revisión más reciente que contenga este hotfix. Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
956909SQL Server 2008 generaciones que se publicaron después del lanzamiento de SQL Server 2008

Solución

El paquete de hotfix elimina el problema. Si se utiliza la instrucción MERGE en el escenario que se describe en la sección "Síntomas" y si elige no aplicar la revisión, siga estos pasos para eliminar este problema:
  1. Vuelva a escribir la instrucción MERGE para que los valores para el origen de combinación estén en una tabla, una tabla temporal o una variable de tabla en lugar de en-alineado en la consulta.
  2. Utilizar indicador de traza 8790. Este indicador de traza obliga el optimizador para utilizar un tipo de plan que se llama a un plan de actualización amplia. Planes de ancho de la actualización no tienen el problema. Este paso se lleva a los riesgos de rendimiento para todas las instrucciones DML. Por lo tanto, debe evitar el uso este paso a menos que sea imposible cambiar la aplicación.
La secuencia de comandos de Transact-SQL siguiente muestra una forma para cambiar la secuencia de comandos para resolver este problema si no se puede aplicar este hotfix.

Por ejemplo, tendrá una secuencia de comandos similar al siguiente:
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);
cambiar la secuencia de comandos de forma que refleje lo siguiente:
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);

Estado

Microsoft ha confirmado que se trata de un problema de los productos de Microsoft enumerados en la sección "La información de este artículo se refiere a:".

Más información

Para obtener más información acerca de qué archivos se ha cambiado y para información acerca de los requisitos previos para aplicar el paquete de actualización acumulativa que contiene la revisión que se describe en este artículo, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
956717Paquete de actualización acumulativa 1 de SQL Server 2008

Referencias

Para obtener más información acerca de la lista de generaciones que están disponibles después del lanzamiento de SQL Server 2008, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
956909SQL Server 2008 generaciones que se publicaron después del lanzamiento de SQL Server 2008


Para obtener más información acerca del modelo incremental de servicio para SQL Server, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
935897Un modelo incremental de servicio está disponible desde el equipo de SQL Server para entregar revisiones para problemas detectados


Para obtener más información sobre el esquema de nomenclatura para las actualizaciones de SQL Server, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
822499Nuevo esquema de nomenclatura para los paquetes de actualización del software de Microsoft SQL Server


Para obtener más información acerca de la terminología relativa de la actualización de software, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
824684Descripción de la terminología estándar utilizada para describir las actualizaciones de software de Microsoft

Referencias

Para obtener más información acerca de los índices no agrupados de SQL Server 2008, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):
http://msdn.microsoft.com/en-us/library/ms179325(SQL.100).aspx

Propiedades

Id. de artículo: 956718 - Última revisión: viernes, 19 de septiembre de 2008 - Versión: 4.0
La información de este artículo se refiere 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
Palabras clave: 
kbmt kbautohotfix kbhotfixserver kbqfe kbpubtypekc kbfix KB956718 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 956718

Enviar comentarios

 

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