假設我有一個已經包含'IsDelete Char(1)'列的表。 每當我對這個表進行刪除處理時,我不會做出實際的刪除命令。SQL刪除更新外鍵主鍵約束
eg. DELETE FROM TableName
但我做了更新命令。
eg. UPDATE TableName SET IsDelete = '1' .....
所以,如果我想爲這個表做參照完整性,我不知道如何做到這一點。 因爲我沒有做出實際的刪除命令。 請解釋我。
假設我有一個已經包含'IsDelete Char(1)'列的表。 每當我對這個表進行刪除處理時,我不會做出實際的刪除命令。SQL刪除更新外鍵主鍵約束
eg. DELETE FROM TableName
但我做了更新命令。
eg. UPDATE TableName SET IsDelete = '1' .....
所以,如果我想爲這個表做參照完整性,我不知道如何做到這一點。 因爲我沒有做出實際的刪除命令。 請解釋我。
首先,最好使用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])
檢查與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;
假設我將您的代碼更改爲FOREIGN KEY(SalesOrderID,IsDeleted)REFERENCES dbo.SalesOrder(SalesOrderID,IsDeleted) ON UPDATE NO ACTION;因爲我想只爲SaleOrder表禁止刪除操作。然後,SaleOrder表是okey,因爲它在刪除時返回外鍵限制消息(SET IsDeleted ='Y')。但不幸的是,SaleOrderDetail無法刪除(SET IsDeleted ='Y')。所以,如果你有其他解決方案,請給我建議。 –
是@Bogdan我已經運行,因爲你告訴UPDATE dbo.SalesOrderDetail SET IsDeleted ='Y'WHERE SalesOrderID = 1;但是我得到消息「UPDATE語句與參考約束衝突」FK_SalesOrderDetail_SalesOrder_SalesOrderID_IsDeleted「衝突發生在數據庫」DBTest_MT「,表」dbo.SalesOrderDetail「中。」 –
如果將FK定義從ON UPDATE CASCADE更改爲ON UPDATE NO ACTION,你會得到那個錯誤。這個新的規範(「更新不行動」)與參照完整性概念本身衝突/矛盾。例如,您不能有兩個'SalesOrderDetail(SalesOrderID = 101; IsDedeleted ='Y'; Qty = 10&SalesOrderID = 101; IsDedeleted ='Y'; Qty = 20)'SalesOrder(SalesOrderID = 101;請將isDeleted = 'N')'。 –
如果你不想從表中刪除以往的記錄,然後更改權限表所以除了sys_admin之外,沒有其他人可以刪除。
通常當您添加一個IS_Deleted列時,最好重命名該表,然後創建一個只有選擇活動記錄的舊錶名的視圖。這將防止你的代碼中斷。
如果您希望在桌面上執行刪除操作時發生更新,則通過觸發器完成更新。在SQL Server觸發器上操作整個批處理,因此請確保觸發器可以處理多行刪除。
我想說的是讓我們假設有2個表叫做Department和Employee。兩個表都有IsDelete列。所以,如果我首先刪除部門「例如更新部門設置Department.IsDelete = 1其中....」。如果已刪除部門已存在於員工,它可能發生打破部門和員工之間的參照完整性。所以在這種情況下,我該如何做出參照完整性約束。因爲我不想編寫這麼多的代碼來檢查。 –
查看Bogdan Sahlean的回答,他舉了一個很好的例子。 –
@MyatThu我編輯了我的答案。 –