SQL使用触发器进行约束

SQL使用触发器进行约束,第1张

SQL使用触发器进行约束

首先,我认为这是一条数据规则,因此应集​​中实施。也就是说,应该由DBMS强制执行数据库约束(或等效约束),以防止所有应用程序写入不良数据(而不是依靠每个应用程序的各个编码器来避免写入不良数据)。

其次,我认为

AFTER
触发器是适当的(而不是
INSTEAD OF
触发器)。

第三,可以使用外键和行级

CHECK
约束来强制执行此 *** 作。

对于约束类型触发器,通常的想法是编写查询以返回错误数据,然后在触发器测试中将该结果为空。

您尚未发布表的许多详细信息,所以我会猜到。我以为

student_number
是一个学生的集合;因为它听起来像一个标识符,所以我将更改名称并假定学生的标识符为
student_id

WITH EnrolmentTallies     AS     (      SELECt teacher_id, COUNT(*) AS students_tally        FROM Enrolment       GROUPBY teacher_id) SELECt *   FROM Teachers AS T       INNER JOIN EnrolmentTallies AS E         ON T.teacher_id = E.teacher_id AND E.students_tally > T.students_tally;

在SQL Server中,触发器定义如下所示:

CREATE TRIGGER student_tally_too_high ON EnrolmentAFTER INSERT, UPDATeASIF EXISTS (SELECT *   FROM Teachers AS T       INNER JOIN (        SELECt teacher_id, COUNT(*) AS students_tally          FROM Enrolment         GROUP  BY teacher_id  ) AS E ON T.teacher_id = E.teacher_id    AND E.students_tally > T.students_tally          )BEGINRAISERROR ('A teachers''s student tally is too high to accept new students.', 16, 1);ROLLBACK TRANSACTION;RETURN END;

但是,还有一些其他注意事项。在每次

UPDATE
访问表之后执行此类查询可能效率很低。您应该使用
UPDATE()
(或
COLUMNS_UPDATED
如果您认为可以依赖列排序)和/或
deleted
inserted
概念表来限制查询的范围以及何时触发查询。您还需要确保事务正确序列化,以防止并发问题。尽管涉及到,但并不复杂。

我强烈推荐《面向数据库专业人员的应用数学》一书,作者是Lex
de Haan,Toon
Koppelaars

,第11章(代码示例是Oracle,但可以轻松移植到SQL
Server)。


无需触发即可实现相同的效果。想法是

(teacher_id,students_tally)
在注册中引用一个超级键,为此将保留一系列独特的学生事件,并进行测试,以确保该序列永远不会超过最大计数。

这是一些简单的SQL DDL:

CREATE TABLE Students ( student_id INTEGER NOT NULL, UNIQUE (student_id));CREATE TABLE Teachers ( teacher_id INTEGER NOT NULL, students_tally INTEGER NOT NULL CHECK (students_tally > 0),  UNIQUE (teacher_id),  UNIQUE (teacher_id, students_tally));CREATE TABLE Enrolment( teacher_id INTEGER NOT NULL UNIQUE, students_tally INTEGER NOT NULL CHECK (students_tally > 0),  FOREIGN KEY (teacher_id, students_tally)    REFERENCES Teachers (teacher_id, students_tally)    ON DELETE CASCADE    ON UPDATE CASCADE,  student_id INTEGER NOT NULL UNIQUE     REFERENCES Students (student_id), student_teacher_sequence INTEGER NOT NULL    CHECK (student_teacher_sequence BETWEEN 1 AND students_tally) UNIQUE (teacher_id, student_id),  UNIQUE (teacher_id, student_id, student_teacher_sequence));

然后添加一些“帮助”存储的过程/函数以保持更新顺序。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5620515.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-15
下一篇2022-12-15

发表评论

登录后才能评论

评论列表(0条)

    保存