2012-04-27 70 views
3

我有一個關於強制約束我的表的問題。 我有一張名爲workon的表格和一張名爲staff的表格,每個工作人員都有特定的標題(主管,授權人,經理......)。我需要確保主管和授權人不能成爲工作桌上的同一員工。他們之間的基數是多對多的。我不知道該怎麼做。 你可以請你提醒我解決這個問題嗎?如何在sql中強制約束?

感謝

+0

哪個DBMS? SQL Server/Oracle等。 – Bridge 2012-04-27 09:19:16

回答

0

考慮下面的查詢

SELECT AssignmentNo, StaffNo 
    FROM worksOnStaff 
WHERE StaffType = 'supervisor' 
INTERSECT 
SELECT AssignmentNo, StaffNo 
    FROM worksOnStaff 
WHERE StaffType = 'authorizer' 

當表satisifes您的約束上面的查詢中的數據將是空的設置即

CHECK (NOT EXISTS (SELECT AssignmentNo, StaffNo 
         FROM worksOnStaff 
         WHERE StaffType = 'supervisor' 
        INTERSECT 
        SELECT AssignmentNo, StaffNo 
         FROM worksOnStaff 
         WHERE StaffType = 'authorizer')); 

問題是,很少有SQL產品允許在一個CHECK約束下的子查詢。

通常的解決方法是在程序代碼中實現相同的邏輯。使用觸發器或強制用戶通過存儲過程更新數據(通過刪除基表上的更新權限),確保從不違反約束。你必須小心地正確地序列化更新,而不要使整個事情像膠水一樣運行。

令人高興的是,有一個很好的書上的題目:

Applied Mathematics for Database Professionals By Lex de Haan, Toon Koppelaars

爲了實現不能申報到DBMS的限制,我們更願意遵循觸發程序策略...喜歡聲明限制,觸發的程序策略不能被顛覆; ...可能會創建一個更易於管理的代碼體系結構......但是,通過觸發器爲這些約束實現高效的數據完整性代碼遠非一項微不足道的任務......但是,通過實現表約束定期併成爲 精通這樣,實施表約束在程序上是一般相當 可行...

執行模型EM6:開轉換效果的屬性加優化查詢

  1. 翻譯正式規範轉換爲約束驗證查詢。
  2. 開發代碼以維護轉換效果。
  3. 設計過渡效果(TE)查詢,確保僅在需要 時運行約束驗證查詢。
  4. 通過使TE查詢 提供可在驗證查詢中使用的值來發現優化約束驗證查詢的方法。
  5. 設計並向數據完整性(DI)代碼添加序列化策略。

他們就如何落實在甲骨文這樣的策略,可以移植到其他SQL產品的全部細節。

0

一些數據庫支持檢查約束:

CREATE TABLE workson 
(
    rowId int NOT NULL, 
    supervisorId int NOT NULL, 
    authorizerId int NOT NULL, 
    -- ... 
    CONSTRAINT chk_Uniqueness CHECK (supervisorId != authorizerId) 
) 
+0

感謝您的迴應,但表中只有staffId屬性。員工職位將定義員工角色。 – user1360341 2012-04-27 06:14:33

+0

@ user1360341 - 然後我不明白你真正想要什麼。你可否請張貼表格結構。 – mrab 2012-04-27 06:25:19

+0

這是我的表架構http://sqlhelp1.blogspot.com.au/。我需要確保主管和授權人不能成爲任何特定工作的同一員工。 – user1360341 2012-04-27 06:33:03