欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL Server 利用触发器对多表视图进行更新的实现方法

程序员文章站 2022-03-02 23:37:26
其步骤就是:利用update操作触发器产生的2个虚拟表【inserted】用来存储修改的数据信息和【deleted】表,然后将对应的数据更新到对应数据表中的字段信息中;...

其步骤就是:利用update操作触发器产生的2个虚拟表【inserted】用来存储修改的数据信息和【deleted】表,然后将对应的数据更新到对应数据表中的字段信息中;

SQL Server 利用触发器对多表视图进行更新的实现方法

1.首先创建3个表:

a.信息表:

use [sql-li]
begin transaction chuangjian_xinxin_tab 
--创建命名为【xinxin_tab】的数据表,同时不允许字段为空
create table xinxin_tab
(
姓名 nvarchar(10) not null,
性别 nvarchar(1) not null,
学号 int not null,
班级 nvarchar(20) not null,
出生日期 date not null,
constraint xuehao_yuesu primary key clustered
([学号]asc)
)
commit transaction chuangjian_xinxi_tab
go

b.明细分数表:

use [sql-li] 
create table fenshu_tab
(
[学号] int not null,
[语文] decimal(3,1) not null,
[数学] decimal(3,1) not null,
[英语] decimal(3,1) not null
)
go

c.综合分数表:

use [sql-li] 
create table zhonghe_tab
(
[姓名] nvarchar(10) not null,
[学号] int not null,
[总分] decimal(4,1) not null,
[平均分] decimal(3,1) not null)
go

2.1.【信息表】和【明细分数表】插入对应表中的数据:

use [sql-li] 
--插入【xinxin_tab】表中的5条记录
insert into [dbo].xinxin_tab ([姓名] ,[学号] ,[性别] ,[班级] ,[出生日期] )
values('李晓峰',6080,'男','计算机','2013-05-03')

insert into [dbo].xinxin_tab ([姓名] ,[学号] ,[性别] ,[班级] ,[出生日期] )
values('李晓峰1',6081,'男','计算机1','2013-05-04')

insert into [dbo].xinxin_tab ([姓名] ,[学号] ,[性别] ,[班级] ,[出生日期] )
values('李晓峰2',6082,'男','计算机2','2013-05-05')

insert into [dbo].xinxin_tab ([姓名] ,[学号] ,[性别] ,[班级] ,[出生日期] )
values('李晓峰3',6083,'男','计算机3','2013-05-06')

insert into [dbo].xinxin_tab ([姓名] ,[学号] ,[性别] ,[班级] ,[出生日期] )
values('张晓',6084,'女','美术','2013-05-07')

--插入【fenshu_tab】表中的5条记录
insert into [dbo].fenshu_tab ([学号] ,[语文] ,[数学] ,[英语] )
values(6080,99.5,98.6,59.2)

insert into [dbo].fenshu_tab ([学号] ,[语文] ,[数学] ,[英语] )
values(6081,93.5,94.3,55.8)

insert into [dbo].fenshu_tab ([学号] ,[语文] ,[数学] ,[英语] )
values(6082,96.5,78.6,58.5)

insert into [dbo].fenshu_tab ([学号] ,[语文] ,[数学] ,[英语] )
values(6083,99.5,68.4,89.2)

insert into [dbo].fenshu_tab ([学号] ,[语文] ,[数学] ,[英语] )
values(6084,99.7,98.7,59.4)
go

【信息表】的数据:

SQL Server 利用触发器对多表视图进行更新的实现方法

【明细分数表】的数据:

SQL Server 利用触发器对多表视图进行更新的实现方法

2.2.运算记录【综合分数表】的数据:

插入【zhonghe_tab】中的数据
use [sql-li] 
--声明3个变量分别用来接收【平均分】,【总分】,【姓名】,和一个控制循环的条件变量@i_while_xuehao
declare @i_while_xuehao int,@zongfen decimal(4,1),@avgfen decimal(3,1),@xingming nvarchar(10);
select @i_while_xuehao =6080;
--使这个变量【@i_while_xuehao】的值指定在【学号】字段上
while(@i_while_xuehao >=6080 and @i_while_xuehao <6085)
begin
--求取【平均分】,【总分】,【姓名】并存在声明的变量中
select @zongfen =(f.语文 +f.数学 +f.英语 ),@avgfen =(f.语文 +f.数学 +f.英语 )/3,@xingming =x.姓名 
from[dbo].xinxin_tab as x inner join [dbo].fenshu_tab as f on x.学号 =f.学号 
where x.学号 =@i_while_xuehao --与【学号同步】
--将其变量的数据插入到【zhonghe_tab】的对应字段上
insert into [dbo].zhonghe_tab ([姓名] ,[学号] ,[平均分] ,[总分] )
values(@xingming ,@i_while_xuehao ,@avgfen ,@zongfen )
select @i_while_xuehao +=1;  --与【学号同步】
end
go

【综合分数表】的数据:

SQL Server 利用触发器对多表视图进行更新的实现方法

3.1.1.创建3个表关联的视图:

use [sql-li] 
go
create view shitu_ffenshu_xinxi(姓名,学号,平均分,总分,班级,出生日期)
as
select top 800 x.姓名 ,f.学号 ,z.平均分 ,z.总分 ,x.班级 ,x.出生日期 
from[dbo].xinxin_tab as x inner join [dbo].fenshu_tab as f on x.学号 =f.学号 
  inner join [dbo].zhonghe_tab as z on f.学号 =z.学号 
  order by f.学号 asc
  go

查看创建的视图:

SQL Server 利用触发器对多表视图进行更新的实现方法

3.2.1.通过视图修改多个数据表的信息????:

update [sql-li].[dbo].[shitu_ffenshu_xinxi]
set [姓名] = 'aaaaa', --此字段在【信息表】中
[平均分] =111  --此次字段在【分数】中
where [学号]=6080
go

结果:

SQL Server 利用触发器对多表视图进行更新的实现方法

SQL Server 利用触发器对多表视图进行更新的实现方法

下面就写个利用触发器对其多表进行更新的方法:

a.这里就利用instead of 代替触发来代替对各表中的字段内的信息进行修改:

use [sql-li] 
go
create trigger trigg_update --创建一个upda触发器dml
--关联到[shitu_ffenshu_xinxi]视图上
on[dbo].[shitu_ffenshu_xinxi]
instead of update --代替触发器执行update功能;【但是只能定义一个增删改的instead of代替触发】。
as
--声明接受变量用于存储【inserted】表上的数据
declare @xingming nvarchar(10),@xuehao int,@avgfen decimal(3,1),@zongfen decimal(4,1),
    @banji nvarchar(20),@chushengriqi date;
    --筛选【inserted】表中学号最小的一行数据
select @xuehao =min(学号) from[inserted] 
--遍历【inserted】表

while(@xuehao is not null)
begin
--将【inserted】表中的数据存放到相应的变量中
select @xuehao =min([学号])from[inserted] where [学号]=@xuehao 
select @xingming=[姓名] from[inserted] where[学号] =@xuehao 
select @avgfen=[平均分]from[inserted] where[学号] =@xuehao 
select @zongfen=[总分] from[inserted] where[学号] =@xuehao 
select @banji =[班级]from[inserted] where[学号] =@xuehao 
select @chushengriqi=[出生日期]from[inserted] where[学号] =@xuehao 

--找出视图中的字段对应相应表的字段
/*因为视图中的[姓名]/[班级]/[出生日期]字段是xinxin_tab 中的字段,故修改【xinxin_tab】中对应的字段
数据之*/
update[dbo].xinxin_tab 
set [姓名]=@xingming ,[班级]=@banji ,[出生日期]=@chushengriqi 
where[学号]=@xuehao 

--道理同上
update[dbo].fenshu_tab 
set[学号]=@xuehao 
where[学号]=@xuehao 

--道理同上
update[dbo].zhonghe_tab 
set[平均分]=@avgfen ,[总分]=@zongfen 
where[学号]=@xuehao 

--修改完成后就开始筛选【inserted】表中下一条数据记录
select @xuehao =min([学号])from[inserted] where[学号]>@xuehao
--然后给while中判断 
end
go

a1.注意的是视图不是数据表没有存放数据,将从【inserted】表中的数据提取后赋给对应数据表内的字段中;

SQL Server 利用触发器对多表视图进行更新的实现方法

对象资源管理器中的图示:

SQL Server 利用触发器对多表视图进行更新的实现方法

 3.万事俱备,开始通过视图修改多表中的数据(验证):

a

use [sql-li] 
--查看未修改前的视图数据信息
select* from[dbo].shitu_ffenshu_xinxi 
go

update[dbo].shitu_ffenshu_xinxi 
--修改【shitu_ffenshu_xinxi】中对应的字段数据
set[姓名]='liyifeng' ,[平均分]=66.6 ,[总分]=88.8 ,[班级]='计算机sqlserver' ,[出生日期]='2013-05-05' 
--修改筛选
where[学号]=6080 
go
--查看修改后的视图数据信息
select* from[dbo].shitu_ffenshu_xinxi 
go

修改前后对比的结果图示:

SQL Server 利用触发器对多表视图进行更新的实现方法

修改后的数据表中的数据:

use [sql-li] 
select* from[xinxin_tab] where[学号]=6080
select* from[fenshu_tab] where[学号]=6080
select* from[zhonghe_tab] where[学号]=6080
go

SQL Server 利用触发器对多表视图进行更新的实现方法

4.触发器在数据库里面就像颗炸弹一样,只要满足气要求就会被触发,就会对数据库里面的数据进行触发修改,所以不需要室就尽量将其关闭掉,用的时候就将其开启:

关闭:

use [sql-li] 
go
disable trigger [dbo].trigg_update --关闭触发器【trigg_update】
on shitu_ffenshu_xinxi
go

SQL Server 利用触发器对多表视图进行更新的实现方法

开启:

use [sql-li] 
go
enable trigger [dbo].trigg_update --开启触发器【trigg_update】
on[dbo].[shitu_ffenshu_xinxi] --触发器所在的视图
go

SQL Server 利用触发器对多表视图进行更新的实现方法

go

希望我写的能为你解决一点问题,还望指教!谢谢!