Scenario:
Stai lavorando come sviluppatore di SQL Server, hai scritto una dichiarazione di aggiornamento per una delle tabelle e hai riportato l'errore sotto.Msg 547, livello 16, stato 0, riga 32
L'istruzione UPDATE era in conflitto con il vincolo REFERENCE "FK_".
Il conflitto si è verificato nel database "YourDatabaseName", tabella "SchemaName.YourTableName", colonna "ColumnName".
L'istruzione è stata terminata.
Come risolvere questo problema?
Soluzione:
Creiamo prima questo errore usando lo script sottostante. Creeremo due tabelle dbo.Customer e dbo.Orders. Le tabelle hanno una relazione chiave primaria-estranea.USE YourDatabaseName GO CREATE TABLE dbo.Customer ( Customerid INT PRIMARY KEY ,FName VARCHAR(100) ,LName VARCHAR(100) ,SSN VARCHAR(10) ) CREATE TABLE dbo.Orders ( OrderId INT Identity(1, 1) ,OrderitemName VARCHAR(50) ,OrderItemAmt INT ,Customer_id INT FOREIGN KEY REFERENCES Customer(CustomerId) ) --insert sample data insert into dbo.Customer (CustomerId,FName, LName,SSN) values (1,'Aamir','Shahzad','000-000-00') insert into dbo.Orders (OrderItemName,OrderItemAmt,Customer_Id) values ('TV',1,1)
Come aggiornare il record quando la colonna è referenziata dal vincolo di chiave esterna in SQL Server |
Ora diciamo se ritieni che il valore CustomerId non sia corretto in dbo.Customer e debba essere aggiornato. Hai scritto di seguito la dichiarazione di aggiornamento per aggiornare CustomerId a 100.
update dbo.Customer set Customerid=100
Otterrai un errore inferiore.
Msg 547, livello 16, stato 0, riga 33 L'istruzione UPDATE era in conflitto con il vincolo REFERENCE "FK__Orders__Customer__1ED998B2". Il conflitto si è verificato nel database "YourDatabaseName", tabella "dbo.Orders", colonna 'Customer_id'. L'istruzione è stata terminata.
Poiché non è presente alcun valore Customer_id=100 nella tabella dbo.Orders, non è possibile aggiornare il record nella tabella di riferimento. Ora hai pensato di correggere prima la tabella padre ( dbo.Orders) e poi posso aggiornare la tabella dbo.Customer.
update dbo.Orders set Customer_Id=100Ancora una volta hai ricevuto l'errore come mostrato di seguito, perché non abbiamo CustomerId=100 disponibile nella tabella dbo.Customer.
Msg 547, livello 16, stato 0, riga 36 L'istruzione UPDATE era in conflitto con il vincolo FOREIGN KEY "FK__Orders__Customer__1ED998B2 ". Il conflitto si è verificato nel database "YourDatabaseName", tabella "dbo.Customer", colonna 'Customerid'. L'istruzione è stata terminata.
Da qui possiamo trovare più soluzioni 1) Invece di aggiornare il record, inserire il record nella tabella di riferimento ( Dbo.Customer), quindi aggiornare il record nella tabella padre (Dbo.Orders) e infine eliminare i record esistenti dalla tabella di riferimento.
--Insert Record in Reference Table First insert into dbo.Customer (CustomerId,FName, LName,SSN) values (100,'Aamir','Shahzad','000-000-00') --Update the Records in Parent Table update dbo.Orders set Customer_Id=100 --Delete the old record from Reference Table Delete from dbo.Customer where CustomerId=1Controlla ora i record nella tabella.
Come aggiornare il valore della colonna quando si fa riferimento al vincolo della chiave esterna in SQL Server |
2) Disattiva il vincolo di chiave esterna e aggiorna i valori manualmente Un'altra soluzione può essere disabilitare il vincolo di chiave esterna, aggiornare i record e infine abilitare nuovamente la chiave esterna.
--Find the Foreign Key Constraint with Table Name USE YourDatabaseName GO Select Schema_name(Schema_id) as SchemaName, object_name(Parent_object_id) as TableName, name as ForeignKeyConstraintName from sys.foreign_keys
Disabilita il vincolo della chiave esterna utilizzando l'istruzione seguente
SintassiALTER TABLE SchemaName.ParentTableNameNOCHECK CONSTRAINT Constraint_Name
Ho usato l'istruzione seguente per disabilitare il vincolo della chiave esterna sulla tabella dbo.Orders.
--Disable Foregin Key by using NOCHECK ALTER TABLE dbo.Orders NOCHECK CONSTRAINT FK__Orders__Customer__2A4B4B5E --Run Update Statements update dbo.Customer set Customerid=100 update dbo.Orders set Customer_Id=100Enable Foreign Key Constraint SyntaxALTER TABLE SchemaName.ParentTableNameCHECK CONSTRAINT Constraint_Name
Eseguo lo script seguente per abilitare il vincolo di chiave esterna sulla tabella dbo.Orders.
--Enable Foreign Key Constraint by using CHECK ALTER TABLE dbo.Orders CHECK CONSTRAINT FK__Orders__Customer__2A4B4B5E
Video demo:l'istruzione UPDATE era in conflitto con il vincolo REFERENCE