2013-09-26 83 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,你向我展示了光:) –