如何在sql中强制执行约束?

时间:2012-04-27 05:54:24

标签: sql

我有一个关于对我的表强制执行约束的问题。 我有一个名为workson的表和一个名为staff的表,每个员工都有特定的标题(主管,授权人,经理......)。我需要确保主管和授权人不能在工作台上是相同的工作人员。他们之间的基数是多对多的。我不知道该怎么做。 你能告诉我解决这个问题吗?

由于

2 个答案:

答案 0 :(得分:0)

某些数据库支持检查约束:

CREATE TABLE workson
(
    rowId int NOT NULL,
    supervisorId int NOT NULL,
    authorizerId int NOT NULL,
    -- ...
    CONSTRAINT chk_Uniqueness CHECK (supervisorId != authorizerId)
)

答案 1 :(得分:0)

考虑以下查询

SELECT AssignmentNo, StaffNo
  FROM worksOnStaff
 WHERE StaffType = 'supervisor'
INTERSECT 
SELECT AssignmentNo, StaffNo
  FROM worksOnStaff
 WHERE StaffType = 'authorizer'

当表格中的数据满足您的约束时,上述查询将是空集,即

CHECK ( NOT EXISTS ( SELECT AssignmentNo, StaffNo
                       FROM worksOnStaff
                      WHERE StaffType = 'supervisor'
                     INTERSECT 
                     SELECT AssignmentNo, StaffNo
                       FROM worksOnStaff
                      WHERE StaffType = 'authorizer' ) );

问题是,很少有SQL产品允许CHECK约束中的子查询。

通常的解决方法是在程序代码中实现相同的逻辑,例如使用触发器或强制用户通过存储过程更新数据(通过删除基表的更新权限),以确保永远不会违反约束。你必须小心地正确地序列化更新,而不是让整个事情像胶水一样运行。

令人高兴的是,有一本关于这个主题的优秀书籍:

Applied Mathematics for Database Professionals By Lex de Haan, Toon Koppelaars

  

为了实现无法向DBMS声明的约束,我们更愿意遵循触发的过程策略......与声明的约束一样,触发的过程策略不能被破坏; ...可能会创建一个更易于管理的代码架构...... [然而]通过触发器为这些约束实现高效的数据完整性代码远非一项微不足道的任务......   但是,您将通过定期实施表约束并成为经验来体验   精通这样做,在程序上实现表约束通常是相当的   可行...

     

执行模型EM6:On-Transition-Effect-Property Plus Optimized-Query

     
      
  1. 将正式规范转换为约束验证查询。
  2.   
  3. 开发代码以维持过渡效果。
  4.   
  5. 设计过渡效果(TE)查询,确保仅在运行时运行约束验证查询   必要的。
  6.   
  7. 通过TE查询发现优化约束验证查询的方法   提供可在验证查询中使用的值。
  8.   
  9. 为数据完整性(DI)代码设计并添加序列化策略。
  10.   

他们提供了有关如何在Oracle中实施此类策略的完整详细信息,该策略可以移植到其他SQL产品中。