2011-08-04 43 views
0

我有三個字段的表T1約束:創建一個字段取決於另一場

id integer 
Vocation integer : VOCATION = 1 or 2 or 3 or 4or 5 
TYPE integer  : TYPE = 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 

類型取決於職業。例如:

  • 如果職= 1,類型應該是= 2或3或4或6
  • 如果職= 2,類型應該是= 4或5,等等

我工作與SQLSERVER2008

我將創建在TYPE約束迫使約束的值是,例如,4或5如果職的值是2,等等

希望對引發劑溶液,所以我創建 帶有sql的觸發器。它接受,但沒有在表

該觸發器(SQL)的代碼

CREATE TRIGGER [dbo].[tg_T1] 
ON [dbo].[T1] 
after INSERT, UPDATE 
AS 

DECLARE @VOCATION int 
DECLARE @TYPE int 

BEGIN 
    IF @VOCATION =1 
    SET @TYPE = 2 
END 

回答

1

沒有影響在扳機,你不能只是引用的列變量。您需要使用INSERTED行集。這表示插入的數據並導致觸發器觸發。花一些時間來閱讀這篇MSDN文章:http://msdn.microsoft.com/en-us/library/aa258254(v=sql.80).aspx

的代碼,它會是這個樣子:

CREATE TRIGGER [dbo].[tg_T1] 
ON [dbo].[T1] 
after INSERT, UPDATE 
AS 

BEGIN 
    UPDATE T1 
    SET TYPE = 
    CASE 
     WHEN VOCATION = 1 THEN 2 
     WHEN VOCATION = 2 THEN 3 
     ... 
    END 
    FROM T1 
    INNER JOIN INSERTED I ON T1.YOUR_PRIMARY_KEY = I.YOUR_PRIMARY_KEY 
END 
+0

您是否認爲這種邏輯會在INSTEAD OF觸發器中找到更好的家?有更新行,然後再次更新,從來沒有坐過好:) –

1

有可能解決這個沒有觸發器,使用檢查約束。但是,您需要確保同時更新VOCATIONTYPE以避免出現異常。也就是說,如果VOCATION = 2TYPE = 5,那麼你將不能夠,例如,更新VOCATION1不改變TYPE的相關值中的一個,無論是你將被允許更新TYPE6VOCATION相應的變化。如果約束條件允許,您仍然可以更新TYPE而不更改VOCATION

這裏的約束定義:

ALTER TABLE dbo.T1 
ADD CONSTRAINT CK_T1_TypeVocation 
    CHECK (
    VOCATION = 1 AND TYPE IN (2, 3, 4, 6) 
    OR 
    VOCATION = 2 AND TYPE IN (4, 5) 
    OR 
    … /* other conditions as necessary */ 
) 
+0

不客氣!看看[@gbn](http://stackoverflow.com/questions/6941281/create-a-constraint-in-a-field-depending-of-another-field/6947711#6947711)的建議。他提供了一個更靈活的解決方案,最終與檢查約束具有相同的效果。設置起來稍微複雜一點,但更容易維護。無論如何,一旦你決定了,請確保[接受](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)答案最終爲你工作。 (這是事情在這個網站上最好的方式。) –

1

一個想法:

  • 創建另一個表(T1Check,說的),只有職業和TYPE
  • 上T1Check主鍵是兩列
  • 用有效配對填充T1Check
  • 在T1上爲VOCATION和TYPE創建一個外鍵,參考T1Check

這意味着數據將只允許在T1中匹配T1Check允許的數據對。

更重要的是,您可以將新的VOCATION和TYPE組合添加到T1Check 而不用更改任何代碼(觸發器)或CHECK約束。這都是數據驅動,更容易維護。

你甚至可以建立一個GUI讓業務用戶在T1Check中定義新的VOCATION/TYPE規則。

+0

這絕對比檢查約束更好,我非常喜歡!但是我開始認爲OP的約束思想與SQL約束的含義不同,即使他們選擇了術語來描述他們的意圖。 *他們的'約束',看起來,應該在VOCATION的改變時強制更改TYPE,因此使用觸發器的想法(不是我同意它......)。 –

相關問題