Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

L'istruzione UPDATE era in conflitto con il vincolo REFERENCE - Tutorial SQL Server/TSQL Parte 76

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=100
 
 
 Ancora 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=1
 
 
 Controlla 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=100

Enable 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