假设我有一张表已包含'IsDelete Char(1)'列。 每当我为这个表做删除过程时, 我没有制作实际的删除命令。
eg. DELETE FROM TableName
但我制作了更新命令。
eg. UPDATE TableName SET IsDelete = '1' .....
因此,如果我想为这些表格制作参考完整性,我不知道如何制作它。 因为我没有制作实际的删除命令。 请解释一下。
答案 0 :(得分:2)
检查使用SQL Server测试的此声明性解决方案(请参阅源代码中的注释):
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;
答案 1 :(得分:1)
如果您不希望从表中删除记录,则更改表的权限,以便除sys_admin之外没有人可以删除。
通常,当您添加IS_Deleted列时,最好重命名该表,然后使用仅选择活动记录的旧表名创建视图。这样可以防止很多代码破坏。
如果要在表上执行删除操作,则需要进行更新,这是通过触发器完成的。在SQL Server中,触发器对整个批处理进行操作,因此请确保触发器可以处理多行删除。
答案 2 :(得分:0)
首先,最好为bit
列使用IsDelete
数据类型。
对于参照完整性,您可以使用REFERENCES
以及不使用IsDelete
列。我没有看到任何问题。
要加入表格,您可以使用:
SELECT *
FROM tbl1
JOIN tbl2 ON tbl1.id=tbl2.id
and tbl1.IsDelete=0
and tbl2.IsDelete=0
<强>被修改强>
部门和员工。
在现实生活中,关闭某个部门并不会解雇员工。通常,您需要先将员工转移到另一个部门(或解雇他们),然后再关闭部门。在这种情况下,FOREIGN KEYS不会有任何问题。
但在现实生活中,经常发生部门先关闭,然后管理层认为如何处理人。
在这种情况下,如果你有如下的参考,你仍然没有任何问题。
ALTER TABLE [Employees] WITH CHECK ADD CONSTRAINT [FK_Employees_Departments] FOREIGN KEY([Department_id])
REFERENCES [Departments] ([Department_id])