求高效触发器

Methodor 2006-10-28 07:06:50
简单描述:使用update触发器修改某列
问题:在下表中增加update触发器,当a011、a021、a031或a041发生变化后,自动将该列变化前后的差值放到a012、a022、a032、a042列中,同时计算a011、a021、a031和a041这4列的最大值(同一行),放到a091列,如果是a011列的值最大,则将a092列设为1,如果是a021列的值最大,则将a092列设为2,如果是a031列的值最大,则将a092列设为3,如果是a041列的值最大,则将a092列设为4。


简单示意表结构:
CREATE TABLE dbo.tb04 (
aa01 int NOT NULL,
a011 decimal(6,3) NOT NULL,
a012 decimal(6,3) NOT NULL,
a021 decimal(6,3) NOT NULL,
a022 decimal(6,3) NOT NULL,
a031 decimal(6,3) NOT NULL,
a032 decimal(6,3) NOT NULL,
a041 decimal(6,3) NOT NULL,
a042 decimal(6,3) NOT NULL,
a991 decimal(6,3) NOT NULL,
a993 smallint NOT NULL ,
CONSTRAINT pk_tb04 PRIMARY KEY NONCLUSTERED (aa01)) ;
CREATE UNIQUE INDEX idx_01 ON dbo.tb04 (...) ;
CREATE UNIQUE INDEX idx_02 ON dbo.tb04 (...) ;
...

实际表结构比较庞大,访问和变化频率也比较高,因此要求触发器的效率非常好
...全文
262 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Methodor 2006-10-29
  • 打赏
  • 举报
回复
ok
Methodor 2006-10-29
  • 打赏
  • 举报
回复
收到
谢谢

准备将getmax函数的char参数换为decimal或int修改一下试试效率如何
HappyQQ 2006-10-28
  • 打赏
  • 举报
回复
高人就是不一样呀!!
Well 2006-10-28
  • 打赏
  • 举报
回复
简单描述:使用update触发器修改某列
问题:在下表中增加update触发器,当a011、a021、a031或a041发生变化后,自动将该列变化前后的差值放到a012、a022、a032、a042列中,同时计算a011、a021、a031和a041这4列的最大值(同一行),放到a091列,如果是a011列的值最大,则将a092列设为1,如果是a021列的值最大,则将a092列设为2,如果是a031列的值最大,则将a092列设为3,如果是a041列的值最大,则将a092列设为4。

/*自定义函数*/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[GetMax]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[GetMax]
GO

/*
函數說明:取字符串裡將分割數據(int)的最大值
創建人:xw_cai
創建日期:2005-10-06
-------------------------------------------------------------------------------
例如:
select dbo.GetMax('80;60;70;100',';')
100
*/
CREATE function GetMax(@vString varchar(100),@cDivisionChar varchar(10))
returns int
as
begin
declare @iCount int
,@iPos int
,@vGetString int
,@iMax int --@vString varchar(100),
if(right(rtrim(@vString),1)<>@cDivisionChar)
begin
set @vString=@vString+@cDivisionChar
end
select @iCount=len(@vString)-len(replace(@vString,@cDivisionChar,''))
,@iPos=1,@vGetString=''
,@iMax=0
while(@iCount>=@iPos)
begin
set @vGetString = cast(left(@vString,charindex(@cDivisionChar,@vString)-1) as int)
if(@iMax<@vGetString)
begin
set @iMax=@vGetString
end
set @vString=right(@vString,len(@vString)-charindex(@cDivisionChar,@vString))
set @iPos=@iPos+1
end
return @iMax
end
GO


---------------------
CREATE TRIGGER [UpdateTbData] ON [dbo].[tb04]
FOR UPDATE
AS

if(update(a011) or update(a021) or update(a031) or update(a041))
begin
update a
set a012=a.a011
,a022=a.a021
,a032=a.a031
,a042=a.a041
,a091=dbo.GetMax(cast(a.a011 as varchar)+';'+cast(a.a021 as varchar)+';'+cast(a.a031 as varchar)+';'+cast(a.a041 as varchar),';')--取得最大值
,a092=case GetMax(cast(a.a011 as varchar)+';'+cast(a.a021 as varchar)+';'+cast(a.a031 as varchar)+';'+cast(a.a041 as varchar),';')
when a.a011 then 1
when a.a021 then 2
when a.a031 then 3
when a.a041 then 4 end
from tb04 a inner join Inserted b
on a.aa01=b.aa01--关键字唯一性(这里要是关键联合查询,要是唯一确定性)

end
xiaoku 2006-10-28
  • 打赏
  • 举报
回复
呵呵
你的逻辑决定了你的触发器就是这样的了!
不过也不是太慢的阿!

表结构太复杂的话,会影响性能,最好分开几个表!

34,838

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧