【发布时间】:2012-08-17 02:20:46
【问题描述】:
在 MS2000 中工作时,我有一个名为 JobOwners 的表,它将工作 (JPSID) 映射到拥有它们的员工 (EmpID)。它还包含他们开始拥有该工作的日期 (DateStarted)、他们停止拥有该工作的日期 (DateEnded) 以及所有权是否处于活动状态 (IsActive)。看起来像这样。
CREATE TABLE JobOwners
(
LogID int NOT NULL IDENTITY(1,1) PRIMARY KEY,
JPSID int NOT NULL FOREIGN KEY REFERENCES JobsPerShift(JPSID),
EmpID int NOT NULL FOREIGN KEY REFERENCES Employees(EmpID),
DateStarted datetime,
DateEnded datetime,
IsActive tinyint NOT NULL
)
应该没有活动的 JPSID 重复,尽管不活动的重复应该没问题。通过一些研究,我发现我可以使用 CHECK 约束上的函数来完成此操作。
CREATE FUNCTION CheckActiveCount(@JPSID INT)
RETURNS INT AS
BEGIN
DECLARE @result INT
SELECT @result = COUNT(*) FROM JobOwners WHERE JPSID = @JPSID AND IsActive = 1
RETURN @result
END
GO
ALTER TABLE JobOwners
ADD CONSTRAINT CK_JobOwners_IsActive
CHECK ((IsActive = 1 AND dbo.CheckActiveCount(JPSID) <= 1) OR (IsActive = 0))
这很好用。它将允许我使用 IsActive 1 插入 JPSID 2,因为没有其他活动的 JPSID 2。它将允许我使用 IsActive 0 插入 JPSID 2,因为当 IsActive 为 0 时不应用检查。当我尝试时它会拒绝但是再次插入带有 IsActive 1 的 JPSID 2,因为它与约束冲突。见下文。
INSERT INTO JobOwners
VALUES(2,2,NULL,NULL,1)
(1 row(s) affected)
INSERT INTO JobOwners
VALUES(2,2,NULL,NULL,0)
(1 row(s) affected)
INSERT INTO JobOwners
VALUES(2,3,NULL,NULL,1)
INSERT statement conflicted with COLUMN FOREIGN KEY constraint...
如果我尝试将其中一条非活动记录更新为活动记录,则会出现此问题。出于某种原因,它允许我。
UPDATE JobOwners SET IsActive = 1
WHERE LogID = 3
(1 row(s) affected)
如果我再次运行相同的语句,则它与约束冲突,但不是第一次。这个应用程序的前端永远不会将非活动记录更改为活动记录,它只会插入一条新记录,但这仍然不是我希望表格允许的事情。
我想知道是否最好将活动的工作所有者分开,并为工作所有者的历史记录一个单独的表格,但我不确定这里的最佳做法。 任何帮助将不胜感激。
谢谢你,
本
【问题讨论】:
-
不要为此使用检查约束。您可以在索引视图上使用唯一索引(尽管在 2000 年,您可能需要做更多工作以确保连接使用的
SET选项与这些兼容) -
@MartinSmith:不需要索引视图。常规的部分索引就足够了:
create unique index idx_active_jpsid on jobowners (jpsid) where isActive = 1但我认为部分索引仅在 2008 年及以后可用 -
@a_horse_with_no_name 2008 及更高版本,问题标记为 2000
-
@MartinSmith:是的,我知道它被标记为 2000,但不是索引视图在 2000 中也不可用吗?
-
@a_horse_with_no_name - 索引视图在 2000 年推出。只是设置选项的要求有点繁琐(需要开启 arithabort)
标签: sql sql-server-2000 constraints