通过检查 inserted 表,判断是否存在价格小于0的记录,若存在,则回滚事务,避免非法数据。
时间: 2025-01-04 21:39:24 浏览: 4
在数据库操作中,为了保证数据的一致性和完整性,可以利用SQL的触发器机制来实现这样的功能。特别是在交易处理中,例如订单插入,我们可以通过在`after insert`触发器中检查新插入的数据是否满足某些条件。在这个例子中,就是检查`inserted`表(在SQL Server中代表新插入的数据)是否有价格小于0的记录。
以下是基本的步骤:
1. **创建触发器**:在数据库中创建一个触发器,比如在SQL Server中:
```sql
CREATE TRIGGER prevent_negative_price
ON [your_table_name] -- 替换为实际表名
AFTER INSERT
AS
BEGIN
IF EXISTS (SELECT * FROM inserted WHERE price < 0)
BEGIN
ROLLBACK TRANSACTION;
raiserror('尝试插入的价格不能为负', 16, 1); -- 提示错误信息
END
END;
```
2. **触发检测和处理**:每当有一条新的记录(inserted表)插入,触发器会被激活并检查价格是否为负。如果是,就会立即回滚当前事务,防止这条非法数据进入数据库,并抛出错误。
相关问题
3.在学生表中创建一个触发器,不允许删除200515001这个学生的记录。思路:使用after触发器,判断inserted表中的学号是否是200515001,如果是,回滚事务(rollback transaction),输出不能删除这个学生记录。验证该操作,并对操作结果截图。
下面是创建触发器的 SQL 代码:
```sql
CREATE TRIGGER tr_no_delete_student_200515001
ON student
AFTER DELETE
AS
BEGIN
IF EXISTS (SELECT 1 FROM deleted WHERE Sno = '200515001')
BEGIN
ROLLBACK TRANSACTION
PRINT 'Cannot delete the record of student 200515001'
END
END
```
该触发器在删除学生表中的记录之后触发。首先,它会检查被删除的记录是否是学号为200515001的学生。如果是,它会回滚事务并输出一条错误信息。
接下来,我们删除学号为200515001的学生的记录:
```sql
DELETE FROM student WHERE Sno = '200515001';
```
执行该语句后,我们可以看到如下结果:
```
(1 行受影响)
Cannot delete the record of student 200515001
Msg 3609, Level 16, State 1, Line 2
The transaction ended in the trigger. The batch has been aborted.
```
这表明触发器已成功阻止了删除学号为200515001的学生的记录,并输出了错误信息。此时,我们可以验证该学生的记录是否仍然存在:
```sql
SELECT * FROM student WHERE Sno = '200515001';
```
查询结果显示该学生的记录仍然存在:
```
Sno Sname Ssex Sage Sdept
----------- ----------- ----------- ----------- -------------
200515001 张三 男 20 计算机科学与技术
(1 行受影响)
```
这表明触发器的功能已经实现。
在sql sever中设计触发器,完成以下功能: 1. student表中当删除某一同学sno时,该同学的所有选课也都要删除,设计一个触发器完成此功能 2. student表中当插入某一同学sno时,若该同学的存在,则拒绝插入并提示“此记录无效”,设计一个触发器完成此功能 3. 在学生表Student上创建一个触发器,要求在向Student中插入数据或修改数据时,学生的年龄不得小于18岁,若小于18岁则将年龄改为18岁。 4. 在课程表Course中创建一个触发器,要求在删除一条课程记录时,先检查该课程是否有被选修记录,若有则提示出错,并回滚Rollback。 5. 创建和测试触发器:向SC表插入数据时,检查插入数据的课程号是否存在于Course表中(创建之前删除Cno的外键约束,比较外键约束和触发器之间的不同)
1. 触发器代码:
```
CREATE TRIGGER delete_student_courses
ON student
AFTER DELETE
AS
BEGIN
DELETE FROM SC WHERE Sno IN (SELECT Sno FROM deleted)
END
```
2. 触发器代码:
```
CREATE TRIGGER check_student_existence
ON student
INSTEAD OF INSERT
AS
BEGIN
IF EXISTS (SELECT * FROM student WHERE Sno = inserted.Sno)
BEGIN
RAISERROR ('此记录无效', 16, 1)
END
ELSE
BEGIN
INSERT INTO student (Sno, Sname, Ssex, Sage, Sdept)
SELECT Sno, Sname, Ssex, Sage, Sdept FROM inserted
END
END
```
3. 触发器代码:
```
CREATE TRIGGER check_student_age
ON student
FOR INSERT, UPDATE
AS
BEGIN
UPDATE student SET Sage = 18 WHERE Sage < 18
END
```
4. 触发器代码:
```
CREATE TRIGGER check_course_selection
ON course
INSTEAD OF DELETE
AS
BEGIN
IF EXISTS (SELECT * FROM SC WHERE Cno IN (SELECT Cno FROM deleted))
BEGIN
RAISERROR ('该课程有被选修记录,无法删除', 16, 1)
ROLLBACK TRANSACTION
END
ELSE
BEGIN
DELETE FROM course WHERE Cno IN (SELECT Cno FROM deleted)
END
END
```
5. 触发器代码:
```
DROP TRIGGER IF EXISTS check_sc_course
GO
CREATE TRIGGER check_sc_course
ON SC
FOR INSERT
AS
BEGIN
IF NOT EXISTS (SELECT * FROM course WHERE Cno IN (SELECT Cno FROM inserted))
BEGIN
RAISERROR ('课程号不存在于Course表中', 16, 1)
ROLLBACK TRANSACTION
END
END
```
需要注意的是,在第五个触发器中,需要先删除SC表中Cno的外键约束,才能创建该触发器。同时,触发器和外键约束的区别在于,触发器可以在插入或修改数据时进行一些自定义的逻辑操作,而外键约束只能保证插入的数据符合外键约束的要求,无法进行其他操作。
阅读全文