我有一個表ab和c列,如果c爲假,那麼我只想允許插入,如果列a和b是唯一的,但如果c是真的,那麼a和b不會需要是獨一無二的。結合UNIQUE和CHECK約束
示例: 表中只能有一個(foo,bar,false),但對於可以有多少(foo,bar,true)沒有限制。
我嘗試了一些像CONSTRAINT blah UNIQUE(a,b)和CHECK(C是TRUE)但我找不出正確的語法。
我有一個表ab和c列,如果c爲假,那麼我只想允許插入,如果列a和b是唯一的,但如果c是真的,那麼a和b不會需要是獨一無二的。結合UNIQUE和CHECK約束
示例: 表中只能有一個(foo,bar,false),但對於可以有多少(foo,bar,true)沒有限制。
我嘗試了一些像CONSTRAINT blah UNIQUE(a,b)和CHECK(C是TRUE)但我找不出正確的語法。
您可以隨時在插入前創建一個檢查所需條件的觸發器。
唯一約束適用於所有行,並且無法指定僅某些行。
檢查約束僅用於單行內的驗證。
達到你的要求,唯一的方法就是做任何以下內容:
1)建立所有刀片由由一個存儲過程。你可以在這裏驗證你的所有邏輯。然而,流氓程序/用戶可以避免使用它並擊敗你的邏輯。
2)創建一個觸發器,驗證您的邏輯並導致無效的插入/更新失敗。應該寫成一次處理一組行
3)創建一個檢查約束,調用用戶定義的函數來進行驗證檢查。這被認爲是不好的做法,應該避免,因爲它們非常慢,並且可能會失敗多行更新。
我建議選項#2觸發器,因爲這正是觸發器的設計目的。
創建返回a和b帶有過濾器WHERE C = false
索引視圖,然後創建視圖的唯一索引。這是一個普遍的做法
如果您有SQL Server 2008中,然後create a unique filtered index代替
存儲過程
觸發(之前或之後)
不知道過濾索引 – devio 2010-04-06 19:23:14
可以使用表約束(取決於SQL引擎 - 不清楚你正在使用哪一個),以確保沒有太多的特定類型的元組。
在火鳥2.1:
fb> CREATE TABLE so2587151 (
> a VARCHAR(16) NOT NULL,
> b VARCHAR(16) NOT NULL,
> c VARCHAR(1) NOT NULL CHECK (c in ('T', 'F')),
> CONSTRAINT so2587151_only_one_false CHECK ( -- begin CONSTRAINT
> NOT EXISTS ( SELECT a, b, COUNT('x')
> FROM so2587151
> WHERE c = 'F'
> GROUP BY 1, 2
> HAVING COUNT('x') >= 1 )
> ) -- end CONSTRAINT
>);
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'T');
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'T');
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'F');
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'F');
Error: Operation violates CHECK constraint on view or table
-Operation violates CHECK constraint SO2587151_ONLY_ONE_FALSE on view or table SO2587151
-At trigger 'CHECK_15'
fb> SELECT * FROM so2587151;
A | B | C
==============
foo | bar | T
foo | bar | T
foo | bar | F
你可以從約束違反錯誤信息看,這是在引擎蓋下Firebird的觸發機制方面實現。
哪個數據庫? mysql,oracle,postgres,ms sql等... – Unreason 2010-04-06 18:23:22
...什麼版本? – gbn 2010-04-06 18:59:29