KB956718 - ΕΠΙΔΙΌΡΘΩΣΗ: Μια πρόταση MERGE ενδέχεται να μην επιβάλλει έναν περιορισμό εξωτερικού κλειδιού όταν η πρόταση ενημερώνει μια στήλη μοναδικού κλειδιού που δεν αποτελεί μέρος ενός κλειδιού συμπλέγματος και υπάρχει μία γραμμή ως προέλευση ενημέρωσης στο SQL Server 2008

Ισχύει για
SQL Server 2008

Σφάλμα #: 50003167 (SQL επείγουσας επιδιόρθωσης)

Για περισσότερες πληροφορίες σχετικά με την κύρια λίστα δομών που κυκλοφόρησαν μετά την κυκλοφορία του SQL, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft:

957826 Πού μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με τις εκδόσεις του SQL Server 2008 που κυκλοφόρησαν μετά το SQL Server 2008 και τις εκδόσεις του SQL Server 2005 που κυκλοφόρησαν μετά το Service Pack 2 του SQL Server 2005

Συμπτώματα

Στο Microsoft SQL Server 2008, ενδέχεται να μην επιβάλλεται περιορισμός εξωτερικού κλειδιού όταν ισχύουν οι ακόλουθες συνθήκες:

  • Εκδίδεται μια πρόταση MERGE.
  • Η στήλη προορισμού της ενημέρωσης έχει ένα μη ομαδοποιημένο μοναδικό ευρετήριο.

Εξετάστε το ακόλουθο σενάριο. Η πρόταση ενημερώνει μια μοναδική στήλη που ονομάζεται Στήλη1 ενός πίνακα που ονομάζεται Πίνακας1. Ο Πίνακας1 αναφέρεται από έναν περιορισμό εξωτερικού κλειδιού από έναν πίνακα που ονομάζεται Πίνακας2.

Το αποτέλεσμα είναι ότι οι γραμμές στον Πίνακα 1 αλλάζουν, ενώ δεν θα έπρεπε. Επιπλέον, ο Πίνακας2 θα έχει γραμμές που έχουν κρεμαστές αναφορές στον Πίνακα 1.

Αυτό το ζήτημα παρουσιάζεται για αυτό το σενάριο, όταν ισχύουν οι ακόλουθες συνθήκες:

  • Η αναφερόμενη στήλη Στήλη1 στον Πίνακα1 δεν αποτελεί μέρος του κλειδιού συμπλέγματος του Πίνακα1.

  • Μόνο μία δυνατή τιμή μπορεί να αντιστοιχιστεί στη στήλη "Στήλη1 ". Για παράδειγμα, συμβαίνει ένα από τα ακόλουθα σενάρια:

    • Η προέλευση συγχώνευσης είναι μία γραμμή δεδομένων. Για παράδειγμα, η προέλευση συγχώνευσης προέρχεται από μία από τις παρακάτω προτάσεις SELECT:

      • select <ConstantValues>
        
      • select <Parameters>
        

      Σημείωση Αυτό το σενάριο είναι το πιο πιθανό σενάριο.

    • Η προέλευση συγχώνευσης είναι στην πραγματικότητα μία γραμμή δεδομένων. Για παράδειγμα, η προέλευση συγχώνευσης προέρχεται από μία από τις παρακάτω προτάσεις SELECT:

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

        Σημείωση <Όνομα_πίνακα.><ColumnName> είναι γνωστό από τον μηχανισμό βελτιστοποίησης ερωτήματος ότι είναι μια μοναδική τιμή.

      • select top 1 <ColumnName> from <TableName>
        
    • Ο σύνδεσμος μεταξύ της προέλευσης συγχώνευσης και του προορισμού συγχώνευσης έχει ένα κατηγόρημα που εγγυάται ότι θα ενημερωθεί μία γραμμή.

    • Ο όρος update ορίζει τη στήλη Column1 σε μια σταθερή τιμή, ανεξάρτητα από την προέλευση συγχώνευσης.

  • Η επιλογή "Κατά την ενημέρωση διαδοχικά" δεν είναι ενεργοποιημένη στον περιορισμό ξένου κλειδιού στον Πίνακα 2.

Σημείωση Συνιστάται να εφαρμόσετε αυτήν την επείγουσα επιδιόρθωση, εάν χρησιμοποιείτε την πρόταση MERGE για να ενημερώσετε στήλες που έχουν μη ομαδοποιημένα μοναδικά ευρετήρια που αναφέρονται από περιορισμούς εξωτερικού κλειδιού.

Επίλυση

Η επιδιόρθωση για αυτό το πρόβλημα κυκλοφόρησε πρώτα στην αθροιστική ενημερωμένη έκδοση 1. Για περισσότερες πληροφορίες σχετικά με τον τρόπο απόκτησης αυτού του πακέτου αθροιστική ενημερωμένη έκδοση για το SQL Server 2008, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft:

956717 Αθροιστική ενημερωμένη έκδοση πακέτου 1 για SQL Server 2008

Σημείωση Επειδή το build που είναι αθροιστικές, κάθε νέα έκδοση της ενημέρωσης κώδικα περιέχει όλες τις επείγουσες επιδιορθώσεις και όλες τις ενημερώσεις κώδικα ασφαλείας που συμπεριλήφθηκαν με την προηγούμενη 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, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft:

956717 Αθροιστική ενημερωμένη έκδοση πακέτου 1 για SQL Server 2008

Παραπομπές

Για περισσότερες πληροφορίες σχετικά με τη λίστα των δομών που είναι διαθέσιμες μετά την κυκλοφορία του SQL Server 2008, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής βάσης της Microsoft:

956909 Οι εκδόσεις του SQL Server 2008 που κυκλοφόρησαν μετά την κυκλοφορία του SQL Server 2008

Για περισσότερες πληροφορίες σχετικά με το μοντέλο τμηματικής συντήρησης για το SQL Server, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft:

935897 Ένα μοντέλο τμηματικής συντήρησης είναι διαθέσιμο από την ομάδα SQL Server για την παροχή επειγουσών επιδιορθώσεων για τα προβλήματα που έχουν αναφερθεί

Για περισσότερες πληροφορίες σχετικά με τη διάταξη ονομασίας για ενημερωμένες εκδόσεις SQL Server, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft:

822499 Νέα διάταξη ονομασίας για τα πακέτα ενημέρωσης λογισμικού του Microsoft SQL Server

Για περισσότερες πληροφορίες σχετικά με την ορολογία ενημερωμένων εκδόσεων λογισμικού, κάντε κλικ στον αριθμό του άρθρου παρακάτω, για να προβάλετε το άρθρο της Γνωσιακής Βάσης της Microsoft:

824684 Περιγραφή της βασικής ορολογίας που χρησιμοποιείται για την περιγραφή ενημερωμένων εκδόσεων λογισμικού της Microsoft

Μη ομαδοποιημένα ευρετήρια στο SQL Server 2008

Για περισσότερες πληροφορίες σχετικά με τα μη ομαδοποιημένα ευρετήρια στο SQL Server 2008, επισκεφθείτε την ακόλουθη τοποθεσία του Microsoft Developer Network (MSDN) στο Web:

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