Triggers for database experiments

First of all, it is stated that the strength of this konjac is weak, so the following operations are for reference only.

Although the code in the article does not have a statement to query the entire table, my suggestion is that you can write several select statements, which is not difficult anyway, isn’t it?

1.  Create a delete trigger in the table Student to realize the cascading deletion of the table Student and the table SC, that is, as long as the tuple student number in the table Student is deleted, the tuple whose SNO is s1 in the table SC will also be deleted ; After creating the trigger, delete the tuple whose student number is '00030' in the Student middle school, and check whether the course selection record with the SNO of '00030' in the table SC is also deleted;

go
create trigger s_delete
on student
instead of delete
as
begin
delete from sc
where sno in(select sno from deleted)
delete from student
where sno in(select sno from deleted)
end

delete from Student
where sno='00030'

1. When the trigger is not executed:

2. After the trigger is executed, the location of the trigger

3. Before and after deletion of sc table and student table:

2.   Add a career planning elective course in the table Course, which is (005, career planning, 4,0014), and create a trigger in the table SC to realize that only students who are over 24 years old (including 24 years old) can choose a career Planning this course, if the age is less than 24 years old, it will output 'age less than 24, can not take this course', the insertion fails, insert ('00001','005',null) and ( '00005','005',null) to see the results, try to use a SQL statement to insert ('00012','005',null) and ('00013','005',null) to see the results, if both The row data is not inserted successfully, explain the reason, and implement a SQL statement by modifying the trigger to insert ('00012','005',null) and ('00013','005',null), ('00013',' 005',null) data inserted successfully;

insert into course values('005','职业规划',4,'0014');

go
create trigger s_insert2
on sc
instead of insert
as
begin
declare @sno2 char(5)
select @sno2 = sno from inserted
if((select cno from inserted)='005' and (select sage from Student where sno = @sno2)<24)
print'年龄小于24,不能选修该门课程'
else
print '成功!'
insert into sc
select * from inserted
where @sno2 in(select sno from inserted)
end

insert into sc values('00001','005',null)
insert into sc values('00005','005',null)

insert into sc values('00012','005',null)
insert into sc values('00013','005',null)

1. Add a new course:

2. After running

3.  Create a change trigger in table SC to realize that the modified grade in table SC cannot be lower than the pre-modified grade. If the modified grade is lower than the pre-modified grade, output 'modified grade is better than before modification Low, cannot be modified', the modification failed, use the update statement to change the grades of the student number 00001 and the course number 001 to 90 and 70 respectively, look at the results, try to use the update statement to change the grades of the course number 001 to 70 , look at the results, the trigger is required to be able to change the score of course 001 below 70 to 70, and the score above 70 will not be modified;

go
create trigger s_update
on sc
after update
as
begin
if(update(score))
begin
declare @score1 numeric(3,1),@score2 numeric(3,1)
select @score1=sc.score from sc -- 修改前
select @score2=score from deleted -- 修改后
if(@score1>@score2)
print '成功!'
end
else
update sc
set sc.Score=@score2 from sc,deleted
where sc.SNo=deleted.SNo and sc.CNo=deleted.CNo
print'修改后的成绩比修改前低,不能修改'
end
-- 有bug,无论输入什么数字,都会更新,而且都会报'修改后的成绩比修改前低,不能修改'

update sc
set score = 90 where sno='00001' and cno = '001'
update sc
set score = 70 where sno='00001' and cno = '001'
update sc
set score = 70 where cno='001' and score < 70

There is a bug in this problem, and I don’t have a good solution so far, I hope some big guys pass by and can give me some pointers.

1. Before modification:

2. After executing the trigger, print after executing the statement:

3. After modification:

4.  Create a trigger in the table Teacher to realize that if the age and salary in the table Teacher are updated, then output 'updated age and salary', if the updated age is not updated salary, output 'updated age', if updated If the salary is updated but the age is not updated, then output 'updated salary', after creation, use the SQL statement to add 1 to the age where tno is 001, add 1 to the salary where tno is 002, and add 1 to both the age and salary when tno is 003 , look at the result;

go
create trigger t_update
on teacher
after update
as
begin
declare @age int,@sal float
select @age = age from deleted
select @sal = sal from deleted
-- 是否就是说inserted存储的是操作之前的,而deleted存储的是操作之后的???
if(@age!=(select age from inserted) and @sal!=(select sal from inserted))
print '更新了年龄和工资'
else if(@age!=(select age from inserted) and @sal=(select sal from inserted))
print '更新了年龄'
else if(@age=(select age from inserted) and @sal!=(select sal from inserted))
print '更新了工资'
end

update Teacher
set age = age+1 where tno='0001'
update Teacher
set sal = sal + 1 where tno='0002'
update Teacher
set age = age + 1,sal = sal+1  where tno='0003'

1. Before modification:

2. After executing the trigger, print after executing the statement:

3. After modification:

5.  On the premise of not deleting the trigger, invalidate the trigger created in question 3;

-- 禁用触发器(让触发器不起作用):
-- ALTER TABLE 表名 DISABLE TRIGGER 触发器名
alter table sc disable trigger s_update

6.  Create a trigger named tri_Delete_C. It is required to first determine whether a trigger named tri_Delete_C already exists in the database. If it exists, delete it first and then create it. When the trigger requires deleting a course, first determine whether the course exists There is a candidate, if there is a candidate, it cannot be deleted, and the execution of the trigger is verified through test data;

if(exists(select * from sysobjects where xtype='tr' and name='tri_Delete_C'))
begin
drop trigger tri_Delete_C
print '已删除'
end
go
create trigger tri_Delete_C
on course
instead of delete
as
begin
if(exists(select * from sc inner join deleted on sc.CNo=deleted.CNo))
print '有人选,不能删除!'
else
declare @cno char(5)
select @cno=cno from deleted
print '没人选,已删除!'
delete from course
where cno in(select cno from deleted)
end

delete from course where cno='005'

insert into course values('006','体育',3,'0010')
delete from course where cno='006'

1. Check if there is a trigger named tri_Delete_C:

Note: Actually no, but it is very convenient to modify the tri_Delete_C trigger we created. If you want to change it, delete it first and then change it:

2. To determine whether the course is eligible:

A. have

b. no

7.  Create a safety trigger in the table Teacher, rejecting users to delete and change the Teacher table in the database, and test the effect by modifying the structure of the Teacher table and deleting the Teacher table after creation (reminder: DDL trigger, key The words are DROP_TABLE, ALTER_TABLE).

go
create trigger safty
on database
for DROP_TABLE,ALTER_TABLE
as
begin
print '拒绝用户对数据库中的Teacher表进行删除和更改操作'
rollback transaction
end

delete from teacher where tno='0002' -- ok,not succeed
drop table teacher					 -- no
alter table teacher add Email varchar(50);--succeed

--DDL触发器标准语法  
-- CREATE [ OR ALTER ] TRIGGER trigger_name   
-- ON { ALL SERVER | DATABASE }   --触发器应用范围为当前数据库|服务器
-- [ WITH <ddl_trigger_option> [ ,...n ] ]  
-- { FOR | AFTER } --指定仅在触发SQL语句中指定的所有操作成功启动后才触发触发器
-- { event_type | event_group } [ ,...n ]  
-- AS { sql_statement  [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier >  [ ; ] }  --触发条件和操作,在尝试操作时,在Transact-SQL语句中指定的触发操作将生效。

The "rollback" method is adopted to reject the user's deletion and modification behavior, wonderful!

Guess you like

Origin blog.csdn.net/m0_64206989/article/details/131018161