使用触发器实现参照完整性

时间:2019-05-04 01:04:46

标签: sql-server

数据库中有2个表,其中包含以下列:

  1. 具有列department的{​​{1}}表(char(4),不为null)
  2. dept_no表,其列为employee(char(4),null)

dept_no列需要使用触发器定义为dept_no表中的主键和department表中的外键。

我认为这是正确的解决方案,使用已删除和已插入的虚拟表来更新/删除相应员工表中的外键:

employee

但是,当我将部门CREATE TRIGGER trig_delete_dept_no ON department AFTER DELETE AS UPDATE employee SET employee.dept_no = NULL FROM deleted WHERE employee.dept_no = deleted.dept_no CREATE TRIGGER trig_update_dept_no ON department AFTER UPDATE AS UPDATE e SET e.dept_no = i.dept_no FROM employee e INNER JOIN inserted i ON e.dept_no = i.dept_no 行更新为其他值时,在employee表中没有看到相应的dept_no更新:

dept_no

删除功能符合预期。更新触发器有什么问题,如何将这两个触发器组合为一个触发器?

2 个答案:

答案 0 :(得分:1)

设计中存在问题。第一件事是您不应将dept_no用作PK(主键)。您需要具有一个IDENTITY或GUID列作为主键,并将该列称为FK(外键)。

这样,您无需担心更改dept_no。

第二点是您不需要触发器。您可以对DELETE操作使用CASCADE选项。

Find more information on CASCADE

答案 1 :(得分:0)

感谢FLICKER和SMor帮助我进行思考。我不认为该任务希望我们通过添加IDENTITY或GUID列来修改表,并且由于我们将严格使用触发器,所以这是我能想到的最佳解决方案:

CREATE TRIGGER trig_delete_dept_no ON department  AFTER DELETE AS 
    UPDATE employee 
    SET employee.dept_no = NULL
    FROM deleted 
    WHERE employee.dept_no = deleted.dept_no

CREATE TRIGGER trig_update_dept_no ON department AFTER UPDATE AS
    IF UPDATE(dept_no)
        BEGIN
        IF (SELECT employee.dept_no
            FROM employee, inserted
            WHERE employee.dept_no = inserted.dept_no) IS NULL
            BEGIN
                ROLLBACK TRANSACTION
                RAISERROR ('Integrity constraint violation, TRIGGER: 
                            trig_update_dept_no, TABLE: department',16,1)
            END
        ELSE PRINT 'Update successful'
        END

只要employee表中没有孤立的记录,这将允许在部门中进行更新。