请想象一下这个小数据库......
图表
删除了无效的 ImageShack 链接 - 志愿者数据库图表
表格
Volunteer Event Shift EventVolunteer
========= ===== ===== ==============
Id Id Id EventId
Name Name EventId VolunteerId
Email Location VolunteerId
Phone Day Description
Comment Description Start
End
协会
志愿者可以报名参加多个事件。
事件可能由多名志愿者组成。
一个事件可能有多个类次。
一次转变只属于一个事件。
一个类次可能只有一名志愿者。
一名志愿者可以轮类工作。
检查约束
我可以创建一个检查约束来 强制执行,不配备任何轮类人员 未报名的志愿者 那个转变的事件?
我可以创建一个检查约束来 强制执行两个重叠的类次 从来没有配备相同的人员 志愿者?
最佳答案
强制数据完整性的最佳位置是数据库。请放心,如果您允许,某些开发人员无论有意还是无意,都会找到一种方法将不一致的内容偷偷带入数据库!
这是一个带有检查约束的示例:
CREATE FUNCTION dbo.SignupMismatches()
RETURNS int
AS BEGIN RETURN (
SELECT count(*)
FROM Shift s
LEFT JOIN EventVolunteer ev
ON ev.EventId = s.EventId
AND ev.VolunteerId = s.VolunteerId
WHERE ev.Id is null
) END
go
ALTER TABLE Shift ADD CONSTRAINT chkSignup CHECK (dbo.SignupMismatches() = 0);
go
CREATE FUNCTION dbo.OverlapMismatches()
RETURNS int
AS BEGIN RETURN (
SELECT count(*)
FROM Shift a
JOIN Shift b
ON a.id <> b.id
AND a.Start < b.[End]
AND a.[End] > b.Start
AND a.VolunteerId = b.VolunteerId
) END
go
ALTER TABLE Shift ADD CONSTRAINT chkOverlap CHECK (dbo.OverlapMismatches() = 0);
以下是新数据完整性检查的一些测试:
insert into Volunteer (name) values ('Dubya')
insert into Event (name) values ('Build Wall Around Texas')
-- Dubya tries to build a wall, but Fails because he's not signed up
insert into Shift (VolunteerID, EventID, Description, Start, [End])
values (1, 1, 'Dunbya Builds Wall', '2010-01-01', '2010-01-02')
-- Properly signed up? Good
insert into EventVolunteer (VolunteerID, EventID)
values (1, 1)
insert into Shift (VolunteerID, EventID, Description, Start, [End])
values (1, 1, 'Dunbya Builds Wall', '2010-01-01', '2010-01-03')
-- Fails, you can't start the 2nd wall before you finished the 1st
insert into Shift (VolunteerID, EventID, Description, Start, [End])
values (1, 1, 'Dunbya Builds Second Wall', '2010-01-02', '2010-01-03')
以下是表定义:
set nocount on
if OBJECT_ID('Shift') is not null
drop table Shift
if OBJECT_ID('EventVolunteer') is not null
drop table EventVolunteer
if OBJECT_ID('Volunteer') is not null
drop table Volunteer
if OBJECT_ID('Event') is not null
drop table Event
if OBJECT_ID('SignupMismatches') is not null
drop function SignupMismatches
if OBJECT_ID('OverlapMismatches') is not null
drop function OverlapMismatches
create table Volunteer (
id int identity primary key
, name varchar(50)
)
create table Event (
Id int identity primary key
, name varchar(50)
)
create table Shift (
Id int identity primary key
, VolunteerId int foreign key references Volunteer(id)
, EventId int foreign key references Event(id)
, Description varchar(250)
, Start datetime
, [End] datetime
)
create table EventVolunteer (
Id int identity primary key
, VolunteerId int foreign key references Volunteer(id)
, EventId int foreign key references Event(id)
, Location varchar(250)
, [Day] datetime
, Description varchar(250)
)
关于sql-server - 如何创建多表检查约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2588072/