KB956718 - แก้ไข: คําสั่ง MERGE อาจไม่บังคับใช้ข้อจํากัดของ Foreign Key เมื่อคําสั่งอัปเดตคอลัมน์คีย์ที่ไม่ซ้ํากันที่ไม่ใช่ส่วนหนึ่งของคีย์การจัดกลุ่มและมีแถวเดียวเป็นแหล่งการอัปเดตใน SQL Server 2008

นำไปใช้กับ
SQL Server 2008

ข้อบกพร่อง #: 50003167 (โปรแกรมแก้ไขด่วนของ SQL)

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับรายการหลักของรุ่นที่วางจําหน่ายภายหลัง SQL ถูกเผยแพร่ ให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความใน Microsoft Knowledge Base:

957826 ที่ที่คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับรุ่น SQL Server 2008 ที่วางจําหน่ายภายหลัง SQL Server 2008 และรุ่น SQL Server 2005 ที่วางจําหน่ายภายหลัง SQL Server 2005 Service Pack 2

อาการ

ใน Microsoft SQL Server 2008 ข้อจํากัดของคีย์นอกอาจไม่ถูกบังคับใช้เมื่อเงื่อนไขต่อไปนี้เป็นจริง:

  • คําสั่ง MERGE จะถูกออก
  • คอลัมน์เป้าหมายของการอัปเดตมีดัชนีเฉพาะที่ไม่เป็นกลุ่ม

ลองพิจารณาสถานการณ์ต่อไปนี้ คําสั่งจะอัปเดตคอลัมน์ที่ไม่ซ้ํากันซึ่งชื่อ Column1 ของตารางที่ชื่อ Table1 Table1 ถูกอ้างอิงโดยข้อจํากัดของคีย์ภายนอกจากตารางที่ชื่อ Table2

ผลลัพธ์คือแถวใน Table1 ถูกเปลี่ยนแปลงเมื่อไม่ควรเป็นอยู่ นอกจากนี้ Table2 จะมีแถวที่มีการอ้างอิงแบบห้อยลงมาไปยัง Table1

ปัญหานี้เกิดขึ้นในสถานการณ์นี้เมื่อเงื่อนไขต่อไปนี้เป็นจริง:

  • คอลัมน์ Column1 ที่อ้างอิงใน Table1 ไม่ได้เป็นส่วนหนึ่งของคีย์การจัดกลุ่มของ Table1

  • คุณสามารถกําหนดค่าที่เป็นไปได้ได้เพียงค่าเดียวเท่านั้นในคอลัมน์ Column1 ตัวอย่างเช่น หนึ่งในสถานการณ์ต่อไปนี้จะเกิดขึ้น:

    • แหล่งข้อมูลที่ผสานคือข้อมูลหนึ่งแถว ตัวอย่างเช่น แหล่งการผสานมาจากคําสั่ง Select คําสั่งใดคําสั่งหนึ่งต่อไปนี้:

      • select <ConstantValues>
        
      • select <Parameters>
        

      หมายเหตุ: สถานการณ์นี้เป็นสถานการณ์ที่เป็นไปได้มากที่สุด

    • ที่จริงแล้วแหล่งข้อมูลที่ผสานคือแถวข้อมูลแถวเดียว ตัวอย่างเช่น แหล่งการผสานมาจากคําสั่ง Select คําสั่งใดคําสั่งหนึ่งต่อไปนี้:

      • select <ColumnName> from <TableName> where <TableName>.<ColumnName> = 1
        

        หมายเหตุ <TableName><ColumnName> เป็นที่รู้จักโดยตัวปรับคิวรีให้เหมาะสมว่าเป็นค่าที่ไม่ซ้ํากัน

      • select top 1 <ColumnName> from <TableName>
        
    • การรวมระหว่างแหล่งที่ผสานและเป้าหมายการผสานมีเพรดิเคตที่รับประกันว่าแถวเดียวจะถูกอัปเดต

    • ส่วนคําสั่ง Update จะตั้งค่าคอลัมน์ Column1 เป็นค่าคงที่ โดยไม่คํานึงถึงแหล่งข้อมูลผสาน

  • The On Update Cascade option is not enabled on the foreign key constraint in Table2.

หมายเหตุ เราขอแนะนําให้คุณใช้โปรแกรมแก้ไขด่วนนี้ถ้าคุณใช้คําสั่ง MERGE เพื่ออัปเดตคอลัมน์ที่มีดัชนีที่ไม่ซ้ํากันแบบคลัสเตอร์ซึ่งถูกอ้างอิงโดยข้อจํากัดของคีย์ภายนอก

การแก้ปัญหา

การแก้ไขปัญหานี้เผยแพร่ครั้งแรกในการอัปเดตสะสม 1 สําหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการขอรับแพคเกจโปรแกรมปรับปรุงสะสมสําหรับ SQL Server 2008 นี้ ให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

956717 แพคเกจการปรับปรุงสะสม 1 สําหรับ SQL Server 2008

หมายเหตุ เนื่องจากรุ่นนี้เป็นแบบสะสม การแก้ไขใหม่แต่ละรุ่นจะมีโปรแกรมแก้ไขด่วนและการแก้ไขความปลอดภัยทั้งหมดที่รวมอยู่ในการแก้ไข SQL Server 2008 รุ่นก่อนหน้า เราขอแนะนําให้คุณพิจารณาใช้การแก้ไขล่าสุดที่มีโปรแกรมแก้ไขด่วนนี้ไปใช้ สําหรับข้อมูลเพิ่มเติม โปรดคลิกที่หมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

956909 รุ่น SQL Server 2008 ที่วางจําหน่ายภายหลัง SQL Server 2008

วิธีแก้ไขปัญหาชั่วคราว

แพคเกจโปรแกรมแก้ไขด่วนจะขจัดปัญหา ถ้าคุณใช้คําสั่ง MERGE ในสถานการณ์ที่อธิบายไว้ในส่วน "อาการ" และถ้าคุณเลือกที่จะไม่ใช้โปรแกรมแก้ไขด่วน ให้ทําตามขั้นตอนเหล่านี้เพื่อขจัดปัญหานี้:

  1. เขียนคําสั่ง MERGE ใหม่เพื่อให้ค่าสําหรับแหล่งข้อมูลการผสานอยู่ในตาราง ตารางชั่วคราว หรือตัวแปรตาราง แทนที่จะอยู่แบบอินไลน์ในคิวรี

  2. ใช้การติดตามแฟล็ก 8790 ค่าสถานะการติดตามนี้บังคับให้ตัวปรับใช้แผนชนิดหนึ่งที่เรียกว่าแผนการอัปเดตแบบกว้าง ไม่มีปัญหาในแผนการอัปเดตแบบกว้าง ขั้นตอนนี้มีความเสี่ยงด้านประสิทธิภาพการทํางานสําหรับคําสั่ง DML ทั้งหมด ดังนั้นคุณควรหลีกเลี่ยงการใช้ขั้นตอนนี้ เว้นแต่จะไม่สามารถเปลี่ยนแอปพลิเคชันได้

สคริปต์ Transact-SQL ต่อไปนี้แสดงวิธีหนึ่งในการเปลี่ยนแปลงสคริปต์ของคุณเพื่อแก้ไขปัญหานี้ ถ้าคุณไม่สามารถใช้โปรแกรมแก้ไขด่วนนี้

ตัวอย่างเช่น คุณมีสคริปต์ที่มีลักษณะดังต่อไปนี้:

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);

เปลี่ยนสคริปต์เพื่อให้มีลักษณะดังนี้:

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);

สถานะ

Microsoft ได้ยืนยันว่านี่เป็นปัญหาที่เกิดขึ้นกับผลิตภัณฑ์ของ Microsoft ที่แสดงไว้ในส่วน "นำไปใช้กับ"

ข้อมูลเพิ่มเติม

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับไฟล์ที่ถูกเปลี่ยนแปลง และข้อมูลเกี่ยวกับข้อกําหนดเบื้องต้นในการใช้แพคเกจการปรับปรุงแบบสะสมที่มีโปรแกรมแก้ไขด่วนตามที่อธิบายไว้ในบทความ Microsoft Knowledge Base นี้ ให้คลิกที่หมายเลขบทความต่อไปนี้เพื่อดูบทความใน Microsoft Knowledge Base:

956717 แพคเกจการปรับปรุงสะสม 1 สําหรับ SQL Server 2008

การอ้างอิง

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับรายการรุ่นที่พร้อมใช้งานหลังจากการวางจําหน่ายของ SQL Server 2008 ให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

956909 รุ่น SQL Server 2008 ที่วางจําหน่ายภายหลัง SQL Server 2008

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับรูปแบบการให้บริการที่เพิ่มขึ้นสําหรับ SQL Server ให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

935897 แบบจําลองการให้บริการที่เพื่มขึ้นมีไว้ให้สําหรับทีมงาน SQL Server เพื่อจัดเตรียมโปรแกรมแก้ไขสําหรับปัญหาที่มีการรายงาน

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับการตั้งชื่อ Schema สําหรับการอัปเดต SQL Server ให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

822499 รูปแบบการตั้งชื่อใหม่สําหรับแพคเกจอัปเดตซอฟต์แวร์ Microsoft SQL Server

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับคําศัพท์ของการปรับปรุงซอฟต์แวร์ ให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:

824684 คําอธิบายเกี่ยวกับคําศัพท์มาตรฐานที่ใช้เพื่ออธิบายการอัปเดตซอฟต์แวร์ของ Microsoft

ดัชนีแบบไม่คลัสเตอร์ใน SQL Server 2008

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับดัชนีแบบไม่คลัสเตอร์ใน SQL Server 2008 โปรดแวะไปที่เว็บไซต์ต่อไปนี้ของ Microsoft Developer Network (MSDN):

https://msdn.microsoft.com/library/ms179325(sql.100).aspx