[英]SQL Delete Update Foreign Key Primary Key Constraint
假設我有一個已經包含“ IsDelete Char(1)”列的表。 每當我對此表進行刪除處理時,我都不會執行實際的Delete命令。
eg. DELETE FROM TableName
但是我做了更新命令。
eg. UPDATE TableName SET IsDelete = '1' .....
因此,如果要對此表進行引用完整性,則不知道如何實現。 因為我不執行實際的刪除命令。 請給我解釋一下。
檢查此聲明性解決方案是否已通過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;
如果您不希望從表中刪除記錄,請更改表的權限,以便除sys_admin之外的任何人都無法刪除。
通常,在添加IS_Deleted列時,最好重命名表,然后使用僅選擇活動記錄的舊表名創建視圖。 這樣可以防止大量代碼被破壞。
如果您希望在表上執行刪除操作后進行更新,則可以通過觸發器來完成。 在SQL Server中,觸發器對整個批次進行操作,因此請確保觸發器可以處理多行刪除。
首先,最好對IsDelete
列使用bit
數據類型。
至於引用完整性,可以使用“ REFERENCES
,也可以不使用“ IsDelete
列”。 我認為沒有任何問題。
對於聯接表,您可以使用:
SELECT *
FROM tbl1
JOIN tbl2 ON tbl1.id=tbl2.id
and tbl1.IsDelete=0
and tbl2.IsDelete=0
編輯
至於部門和員工。
在現實生活中,關閉部門並不意味着要解雇雇員。 通常,您需要先將員工轉移到另一個部門(或解雇他們),然后關閉部門。 在這種情況下,外鍵不會有任何問題。
但是在現實生活中,經常會發生這樣的情況:首先關閉部門,然后管理層考慮與人打交道。
在這種情況下,如果您具有以下參考資料,您仍然不會有任何問題。
ALTER TABLE [Employees] WITH CHECK ADD CONSTRAINT [FK_Employees_Departments] FOREIGN KEY([Department_id])
REFERENCES [Departments] ([Department_id])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.