假设我有一个名为 ProjectTimeSpan 的表(我没有,仅作为示例!),其中包含 StartDate 和 EndDate
我还有一个名为 SubProjectTimeSpan 的表,还包含名为 StartDate 和 EndDate 的列,我想在其中设置检查约束,这使得无法将StartDate和EndDate设置为 ProjectTimeSpan.StartDate 之外的值 ProjectTimeSpan.EndDate
知道关于其他表值的检查约束......
这可能吗?
答案 0 :(得分:39)
在回答您对GSerg答案的评论时,这是使用函数的示例检查约束:
alter table YourTable
add constraint chk_CheckFunction
check (dbo.CheckFunction() = 1)
您可以在其中定义如下功能:
create function dbo.CheckFunction()
returns int
as begin
return (select 1)
end
允许该函数引用其他表。
答案 1 :(得分:14)
您可以创建一个user-defined function来执行检查并返回1或0,然后在其上创建check
约束,提供项目ID和日期作为参数。
答案 2 :(得分:6)
将ProjectTimeSpan
表的键的复合键与StartDate
和EndDate
列组合在一起,然后在SubProjectTimeSpan
表中使用此复合键作为外键引用。这样您就可以在CHECK
表中编写必要的行级SubProjectTimeSpan
约束,例如
CREATE TABLE ProjectTimeSpan
(
project_ID INTEGER NOT NULL UNIQUE, -- key
StartDate DATE NOT NULL,
EndDate DATE NOT NULL,
CHECK (StartDate < EndDate),
UNIQUE (project_ID, StartDate, EndDate) -- compound key
-- other project columns here...
);
CREATE TABLE SubProjectTimeSpan
(
project_ID INTEGER NOT NULL,
StartDate DATE NOT NULL,
EndDate DATE NOT NULL,
FOREIGN KEY (project_ID, StartDate, EndDate)
REFERENCES ProjectTimeSpan (project_ID, StartDate, EndDate)
ON DELETE CASCADE
ON UPDATE CASCADE,
sub_StartDate DATE NOT NULL,
sub_EndDate DATE NOT NULL,
CHECK (sub_StartDate < sub_EndDate),
CHECK (StartDate <= sub_StartDate), -- sub project can't start before main project
CHECK (sub_EndDate <= EndDate) -- sub project can't end after main project
-- other sub project columns here...
);
答案 3 :(得分:1)
您肯定可以做到这一点,正如答案所示。但是,您应该注意,SQL Server似乎在使用UDF的CHECK CONSTRAINT
上遇到问题:
https://dba.stackexchange.com/questions/12779/how-are-my-sql-server-constraints-being-bypassed
答案 4 :(得分:0)
您需要在父表和子表上添加约束,因为子项目不能超出项目范围,但项目范围也不能移出所有子项目。
在这种情况下,您应该使用事务推迟检查上层(Web服务,应用程序)上的约束,以确保在两个表上进行多次查询后数据处于有效状态!