--测试表
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

解决方案 »

  1.   

    楼上的触发器还有不算严谨的地方
    修改为
    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的转化,将遇到的类似的问题好好归类总结。
      

  2.   

    to zhaoanle(zhao)
    操作数据库中的数据有三种人用三种方法:
    DBA:可以直接打开表修改数据。
    Programmer:可以通过SQL语句修改数据。
    User:通过Programmer的转化,用届面修改数据。
    用触发器保持数据引用完整性的时候,应该完全限制住这三种情况。
    你的方法:
    完全不能限制第一种情况(我直接手改班级字段)。
    可以限制住一部分第二种情况(如楼上的回复update 学生名单表 set 学号='20053301' where 学号='20054401')。
    可以完全限制住第三种情况。