2013-09-26 43 views
0

我需要爲我的一個SQL表創建一個唯一的約束,這也將檢查兩個case語句。這在Oracle中工作正常。但是我無法在SQL Server 2008中工作。我將這兩個查詢放在這裏。在包含case語句的SQL Server中創建約束條件

ORACLE(正常工作):

CREATE UNIQUE INDEX UK2_TR_ASSESSMENTEMPLOYEE ON TR_ASSESSMENTEMPLOYEE 
(CASE WHEN ("EMPLOYEEID" IS NOT NULL AND "SCHEDULE" IS NULL) THEN NULL 
ELSE "EMPLOYEEID" END , CASE WHEN "SCHEDULE" IS NULL THEN NULL 
ELSE "SCHEDULE" END) 

SQL服務器:

Alter table TR_ASSESSMENTEMPLOYEE 
Add Constraint UK2_TR_ASSESSMENTEMPLOYEE Unique 
(
CASE WHEN EMPLOYEEID Is Not NULL AND SCHEDULE IS NULL THEN NULL ELSE EMPLOYEEID, 
CASE WHEN SCHEDULE IS NULL THEN NULL ELSE SCHEDULE 
) 

請救救我。提前致謝。

+0

我不確定它可能在SQL服務器中......也許嘗試在您的CASE語句中添加'END'關鍵字,並嘗試使用CREATE UNIQUE INDEX語法而不是ADD ADDTRATRA,但我認爲它會不行。但是我沒有看到創建這種'UNIQUE'約束的目的。 – Yann39

回答

0

我會在前面說這個Oracle約束的目的並不完全清楚。

好像在Oracle實例中,第二CASE說法是多餘的,可以簡化到SCHEDULE列,沒有額外的代碼,即:

CREATE UNIQUE INDEX UK2_TR_ASSESSMENTEMPLOYEE ON TR_ASSESSMENTEMPLOYEE 
(CASE WHEN ("EMPLOYEEID" IS NOT NULL AND "SCHEDULE" IS NULL) THEN NULL 
ELSE "EMPLOYEEID" END , "SCHEDULE") 

SQL Server不支持唯一約束計算標準。實現類似的行爲的一種方法是創建一個計算列和底座上的約束:

ALTER TABLE TR_ASSESSMENTEMPLOYEE 
ADD EMPLOYEEID_CALC AS (CASE WHEN EMPLOYEEID IS NOT NULL AND SCHEDULE IS NULL THEN NULL ELSE EMPLOYEEID END) 

ALTER TABLE TR_ASSESSMENTEMPLOYEE 
ADD CONSTRAINT UK2_TR_ASSESSMENTEMPLOYEE UNIQUE 
(EMPLOYEEID_CALC,SCHEDULE) 

然而,這可能不會給你你想要的行爲 - 在SQL Server中,UNIQUE約束do not allow duplicate NULL keys(違反ANSI SQL標準)。

如果你在SQL 2008或更高版本您可以使用過濾唯一索引得到你想要的行爲(假設這是強制唯一性,其中EMPLOYEEIDSCHEDULE都沒有NULL

CREATE UNIQUE INDEX UK2_TR_ASSESSMENTEMPLOYEE 
ON TR_ASSESSMENTEMPLOYEE(EMPLOYEEID, SCHEDULE) 
WHERE EMPLOYEEID IS NOT NULL AND SCHEDULE IS NOT NULL 
+0

我認爲Ed的第二個解決方案是要走的路!假定您的版本級別> = 2008,即支持篩選索引。 –

+0

謝謝@Ed,你向我展示了光:) –