简体   繁体   中英

SQL Delete Update Foreign Key Primary Key Constraint

Let's say I have a table which already include 'IsDelete Char(1)' Column. Whenever I make delete process for this table, I don't make actual Delete command.

eg. DELETE FROM TableName 

But I make Update command.

eg. UPDATE TableName SET IsDelete = '1' .....

So if I want to make Referential Integrity for this tables, I don't know how I can make it. Because I don't make actual delete command. Please explain me.

Check this declarative solution tested with SQL Server (see comments from source code):

CREATE TABLE dbo.SalesOrder
(
    SalesOrderID INT IDENTITY(1,1)
    ,OrderDate DATETIME NOT NULL
    ,IsDeleted CHAR(1) NOT NULL DEFAULT 'N'
    ,CONSTRAINT PK_SalesOrder PRIMARY KEY (SalesOrderID)
    ,CONSTRAINT CK_SalesOrder_IsDeleted CHECK(IsDeleted IN ('Y','N'))
);

CREATE TABLE dbo.SalesOrderDetail
(
    SalesOrderDetailID INT IDENTITY(1,1)
    ,Qty DECIMAL(8,2) NOT NULL
    ,UnitPrice DECIMAL(8,2) NOT NULL
    ,IsDeleted CHAR(1) NOT NULL DEFAULT 'N'
    ,SalesOrderID INT NOT NULL
);

--We need this index to create the next foreign key constraint
CREATE UNIQUE NONCLUSTERED INDEX IUN_SalesOrder_SalesOrderID_IsDeleted
ON  dbo.SalesOrder(SalesOrderID, IsDeleted);

--If we "delete" (UPDATE dbo.SalesOrder SET IsDeleted = "Y" ...) a row from dbo.SalesOrder table, 
--then this modification (... SET IsDeleted = "Y" ...) will be propagated to dbo.SalesOrderDetail table
--because of ON UPDATE CASCADE clause
ALTER TABLE dbo.SalesOrderDetail
ADD CONSTRAINT FK_SalesOrderDetail_SalesOrder_SalesOrderID_IsDeleted
FOREIGN KEY (SalesOrderID, IsDeleted) REFERENCES dbo.SalesOrder(SalesOrderID, IsDeleted)
ON UPDATE CASCADE;

INSERT  dbo.SalesOrder (OrderDate)
SELECT  '20110101'
UNION ALL
SELECT  '20110202'
UNION ALL
SELECT  '20110303';

INSERT  dbo.SalesOrderDetail (Qty, UnitPrice, SalesOrderID)
SELECT  1,10,1 UNION ALL SELECT 1,11,1 UNION ALL SELECT 1,12,1
UNION ALL 
SELECT 2,20,2
UNION ALL 
SELECT 3,30,3 UNION ALL SELECT 3,31,2;

SELECT  *
FROM    dbo.SalesOrder
SELECT  *
FROM    dbo.SalesOrderDetail 

--Test "DELETE"/UPDATE statement
UPDATE  dbo.SalesOrder 
SET     IsDeleted = 'Y'
WHERE   SalesOrderID = 1;

--Now, we can check SalesOrderDetail rows ([Status] values WHERE [SalesOrderID]=1)
SELECT  *
FROM    dbo.SalesOrder
SELECT  *
FROM    dbo.SalesOrderDetail 

DROP TABLE dbo.SalesOrderDetail;    
DROP TABLE dbo.SalesOrder;

If you don't want records deleted from the table ever, then change the rights to the table so no one except the sys_admin can delete.

Often when you add a IS_Deleted column it is best to rename the table and then create a view with the old table name that only select active records. This will prevent alot of your code from breaking.

If you want an update to happen if you do a delete on the table, that is done through a trigger. In SQL Server triggers operate on the whole batch,so make sure the trigger can handle multiple row deletes.

First, it's better to use bit datatype for IsDelete column.

As for Referential Integrity, you can use REFERENCES as well as without IsDelete Column. I don't see any problems with that.

For joining tables you can use:

SELECT *
FROM tbl1 
     JOIN tbl2 ON tbl1.id=tbl2.id 
                  and tbl1.IsDelete=0
                  and tbl2.IsDelete=0

Edited

As for Department and Employees.

In real life closing of a department doesn't meen firing of its employees. Normaly you need to move the employees to another department (or fire them) first and then close department. In this case, you will not have any problems with FOREIGN KEYS.

But in real life it often happens that department are closed first and then the management thinks what to do with people.

In this case, if you have reference as follows you still will not have any problems.

ALTER TABLE [Employees]  WITH CHECK ADD  CONSTRAINT [FK_Employees_Departments] FOREIGN KEY([Department_id])
REFERENCES [Departments] ([Department_id])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM