3

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

谢谢

4

2 回答 2

0

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

CREATE TABLE workson
(
    rowId int NOT NULL,
    supervisorId int NOT NULL,
    authorizerId int NOT NULL,
    -- ...
    CONSTRAINT chk_Uniqueness CHECK (supervisorId != authorizerId)
)
于 2012-04-27T06:07:02.000 回答
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约束中使用子查询。

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

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

Lex de Haan、Toon Koppelaars 为数据库专业人员提供应用数学

对于无法向 DBMS 声明的约束的实现,我们更倾向于遵循触发程序策略……和声明的约束一样,触发程序策略不能被颠覆;...可能会创建一个更易于管理的代码架构 ...[然而]通过触发器为这些约束实现有效的数据完整性代码绝非易事...但是,您将通过定期实现表约束来体验这一点并且精通这样做,在程序上实现表约束通常是非常可行的......

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

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

他们详细介绍了如何在 Oracle 中实施这种可以移植到其他 SQL 产品的策略。

于 2012-04-27T08:33:53.250 回答