--测试表
create table 学生名单表(姓名 varchar(10),学号 varchar(10),班级 varchar(10))
create table 班级表(班级编号 varchar(2),班级名称 varchar(10))create trigger test
on 学生名单表
for insert
as
begin
update 学生名单表 set 学生名单表.班级=b.班级名称 from 班级表 b where substring(学生名单表.学号,5,2)=b.班级编号 and 学生名单表.班级 is null
endinsert 班级表 values('11','一班')
insert 班级表 values('22','二班')--测试
insert 学生名单表(姓名,学号) values('李三','20051108')
insert 学生名单表(姓名,学号) values('李二','20052202')
insert 学生名单表(姓名,学号) values('李一','20053301')select * from 学生名单表
select * from 班级表
/*结果
姓名 学号 班级
李三 20051108 一班
李二 20052202 二班
李一 20053301 NULL
create table 学生名单表(姓名 varchar(10),学号 varchar(10),班级 varchar(10))
create table 班级表(班级编号 varchar(2),班级名称 varchar(10))create trigger test
on 学生名单表
for insert
as
begin
update 学生名单表 set 学生名单表.班级=b.班级名称 from 班级表 b where substring(学生名单表.学号,5,2)=b.班级编号 and 学生名单表.班级 is null
endinsert 班级表 values('11','一班')
insert 班级表 values('22','二班')--测试
insert 学生名单表(姓名,学号) values('李三','20051108')
insert 学生名单表(姓名,学号) values('李二','20052202')
insert 学生名单表(姓名,学号) values('李一','20053301')select * from 学生名单表
select * from 班级表
/*结果
姓名 学号 班级
李三 20051108 一班
李二 20052202 二班
李一 20053301 NULL
修改为
create trigger test
on 学生名单表
for insert,update
as
begin
update 学生名单表
set 学生名单表.班级=b.班级名称
from 班级表 b ,inserted i
where substring(学生名单表.学号,5,2)=b.班级编号 and
学生名单表.学生编号=i.学生编号(假设学生编号为主键)
end
楼上的方法有一个问题,如果
insert 学生名单表(姓名,学号,班级) values('李一','20053301','abcd')
这样的话,触发器虽然被触发了,但是没有更新数据。
另
楼上的方法仅仅适用于insert的时候,那么update的时候呢?
如update 学生名单表 set 学号='20053301' where 学号='20054401'
楼上的触发器由于是for insert,那么update的时候需要重新写一个触发器。
同样是用于保持数据引用完整性的触发器,既然写,就应该写在一起(根据模块的内聚原理)。
楼主,学习触发器的时候:
一、搞清楚临时表inserted和deleted的原理。
二、学会用update ... set ... from
我认为触发器(保持数据引用完整性)的精髓就在于在update中用from。
三、结合关系型数据库理论搞清1NF->2NF->3NF的转化,将遇到的类似的问题好好归类总结。
操作数据库中的数据有三种人用三种方法:
DBA:可以直接打开表修改数据。
Programmer:可以通过SQL语句修改数据。
User:通过Programmer的转化,用届面修改数据。
用触发器保持数据引用完整性的时候,应该完全限制住这三种情况。
你的方法:
完全不能限制第一种情况(我直接手改班级字段)。
可以限制住一部分第二种情况(如楼上的回复update 学生名单表 set 学号='20053301' where 学号='20054401')。
可以完全限制住第三种情况。