使用CHECK约束执行业务规则
2008-12-31 10:16:59 来源:WEB开发网等待一秒钟,Jefferson没有被标记成一个管理人员但是他的引擎允许他的奖金比例变成7.5%。为什么会发生这种情况呢?再次回顾CHECK约束是用于检查TRUE/FALSE条件的。看看我们的模式,IS_MANAGER被声明成NULL。由于这个字段中的任何空值都会导致CHECK的IS_MANAGER条件等同于不知道的并且导致CASE表达求取我们的默认布尔值为零。当使用等于零的字段时,这是一个需要明白的地方。有很多种方法可以纠正这点。其中一种是把IS_MANAGER标记定义为NOT NULL从而把NULL值转化为零。如果你不能改变这个模式,那么另外的方法就是把CASE重新写到NULL IS_MANAGER 标记的账户中。下面是其中一种重写CASE的方法。(你可能有自己的更改;我的版本是为了达到例证的目的)。
TRUNCATE TABLE DBO.EMPLOYEE
GO
ALTER TABLE DBO.EMPLOYEE
DROP CONSTRAINT CK_EMPLOYEE_BONUSPCT
GO
ALTER TABLE DBO.EMPLOYEE
ADD CONSTRAINT CK_EMPLOYEE_BONUSPCT
CHECK (CASE WHEN IS_MANAGER IS NULL AND BONUSPCT >= 5.00 THEN 1
WHEN IS_MANAGER <> 1 AND BONUSPCT >= 5.00 THEN 1
ELSE 0 END = 0)
GO
INSERT INTO DBO.EMPLOYEE (FIRSTNAME, LASTNAME, IS_MANAGER, SALARY, BONUSPCT)
SELECT 'JAMES', 'MADISON', NULL, 60000, 5.50
GO
执行一个新员工Madison,的脚本,我们可以看到现在这个引擎成功捕捉了这个条件。
图六
现在你可能在想“我打赌我能写一个纯量函数来读取我整个表并且执行一个真实的表级别CHECK以便检查超过的数目和总量”。你是对的,你可以做到。但是正如SQL Server MVP David Portas所提出的,这里也有风险。
正如你看到的,CHECK约束是执行单个和多个字段域完整性而不需要写专门的触发器或者存储过程代码的强有力的方法。
更多精彩
赞助商链接