Check检查约束可以与另一个表相关吗?

Jac*_*one 31 sql sql-server sql-server-2005

假设我有一个名为ProjectTimeSpan的表(我没有,仅作为示例!)包含StartDateEndDate列.

而且,我有叫另一个表SubProjectTimeSpan,还含有列称为起始日期结束日期,在这里我想设置一个检查约束,使得它不可能起始日期日期和结束日期设置为值"外"的ProjectTimeSpan.StartDateProjectTimeSpan.EndDate

一个检查约束的种类知道关于另一个表中的值...

这可能吗?

And*_*mar 42

在回答您对GSerg答案的评论时,这是使用函数的示例检查约束:

alter table YourTable
add constraint chk_CheckFunction
check (dbo.CheckFunction() = 1)
Run Code Online (Sandbox Code Playgroud)

你可以在哪里定义函数:

create function dbo.CheckFunction()
returns int
as begin
    return (select 1)
end
Run Code Online (Sandbox Code Playgroud)

该函数允许引用其他表.

  • 此解决方案存在在源表中修改的行可能破坏参照完整性的风险。您可以通过在源表上添加触发器来检查另一个表上的检查约束来避免这种风险,就像这样。`CREATE TRIGGER MyTrigger ON dbo.SourceTable AFTER UPDATE AS BEGIN ALTER TABLE dbo.ReferencingTable WITH CHECK CHECK CONSTRAINT TheConstraint END ` (4认同)

GSe*_*erg 16

您可以创建一个用户定义的函数来执行检查并返回1或0,然后check在其上创建约束,提供项目ID和日期作为参数.

  • 那个检查约束会是什么样子? (2认同)
  • @GSerg:"改变父项目日期......我无法想象可能就是这样" - 作为一名项目经理,我可以向你保证`EndDate`会改变;) (2认同)

one*_*hen 6

ProjectTimeSpan表的键的复合键与StartDateEndDate列组合在一起,然后使用此复合键作为SubProjectTimeSpan表中的外键引用.这将使您能够CHECKSubProjectTimeSpan表中编写必要的行级约束,例如

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...
);
Run Code Online (Sandbox Code Playgroud)

  • 这只有在您想要允许更改父项目日期时才有意义......这没有意义.考虑:一个主要项目,需要1个月才能完成.由于财务上的孤岛危机(原文如此),你不得不推迟它('startdate`和`enddate`必须得到+1个月).但你不能这样做,因为那时对子项目的检查将失败(子日期现在在父日期之外).并且您无法在更改其父日期之前更改子项目日期.僵局. (3认同)