2012-08-29 79 views
2

我有以下的列在Oracle表測試儀:的Oracle SQL約束where子句

  • TesterID
  • TesterName
  • ISDEFAULT
  • APPLICATION_ID

TesterID是主鍵。 現在我希望只能有一個Default Tester,這意味着只有一個Tester可以在應用程序ID處具有IsDefault = Y的值。

我有約束試了一下:

alter table Tester add constraint Tester_ISDEFAULT UNIQUE(IsDefault,Application_ID); 

是否有可能使在哪裏ISDEFAULT = Y的唯一關鍵?

感謝您的幫助!

回答

6

未與UNIQUE約束。但是,你可以使用一個UNIQUE INDEX代替:

CREATE UNIQUE INDEX ApplicationId_Default_Y ON tester (
    CASE WHEN IsDefault = 'Y' 
     THEN ApplicationId 
     ELSE NULL 
    END 
); 

這裏有一個DEMO

+0

你好,它的工作原理,但我不知道如何。您將IsDefault設置爲索引?什麼意思,然後applicationid,否則爲空? –

+0

基本上,當'IsDefault ='Y''時,您將其應用程序ID存儲在索引中。因此,因爲它是一個* unique *索引,所以如果你嘗試在索引中使用IsDefault = Y再次插入相同的應用程序ID,它將拋出一個異常(因爲該應用程序ID已經在索引中)。 –

+0

只是擴大Joao的解釋 - 通常稱爲「基於功能的索引」。它利用了這樣的事實:如果整個密鑰都是NULL,Oracle不會在索引中存儲任何內容;所以這個索引只在IsDefault ='Y'時才存儲ApplicationId。此外,它是一個唯一的索引,所以它保證只有一行給定的ApplicationId,其中IsDefault ='Y'。 –

0

該約束不起作用,因爲這意味着每個Application_ID只能有兩行 - 一個使用IsDefault = 0,另一個使用IsDefault = 1。

您可以通過觸發器強制執行此邏輯。或者,爲什麼不在應用程序邏輯中強制執行?

create unique index tester_isdefault on tester 
    (case when isdefault='Y' then application_id end); 

由於Oracle不創建的索引條目的鍵是所有空,僅排在那裏ISDEFAULT =」:

+0

+1觸發選項 – sundar

+2

使用觸發器面對突變錯誤,否則你必須發明一種技巧來擊敗它。如此獨特的聯邦調查局 –

1

你可以用一個基於函數的唯一索引,而不是約束這樣做Y'將出現在索引中。

0

創建測試儀上唯一索引tester_ui_1(解碼(is_default, 'Y',0,tester_id)APPLICATION_ID)