您的位置:首页 > 数据库

sql server编写触发器

2017-04-11 15:03 288 查看
最近生产环境上出现了些数据层面的问题,以前关联表的数据用传输工具进行传输,这样时间上会有差异。为了解决这一问题,现要求用触发器实现。

具体需求如下:现有一张表treport,包含reportid,classids等字段,其中classids由一个或多个栏目值组成。而每个栏目值都是以C开头,每两个栏目值中间用','间隔,即使只有一个栏目值,也以','结尾。现要求往treport表插入一条数据的同时,往关联表tclasstree_report也插入相关数据,要求只插入reportid,classid字段。其中classid是classids中的每个单独栏目值,即classids有两个栏目值,就分别获取两个栏目,往tclasstree_report表中插入两条数据,以此类推……

需求示例如下:

treport表数据如下:

ID             ReportID         ClassIDs

1132877 R5035181      C1000,

1132881 R5035173      C732,C113,C751,

1132882 R5035174      C732,C69,

1132883 R5035175      C732,C123,C124,

1132884 R5035176      C732,C139,C1143,

tclasstree_report表数据如下:

ID              ReportID     ClassID

7185280 R5035173   C732

7185281 R5035173   C113

7185282 R5035173   C751

7185283 R5035174   C732

7185284 R5035174   C69

7185285 R5035175   C732

7185286 R5035175   C123

7185287 R5035175   C124

7185288 R5035176   C732

7185289 R5035176   C139

7185290 R5035176   C1143

7185270 R5035181   C1000

刚开始的时候,想着以C出现的次数为栏目个数,然后依次截取各个栏目,编写触发器脚本如下:

create trigger TRIG_TREPORT_TCLASSTREE
on treport
for insert
as
begin
declare @len int;
select @len=len(classids)-len(replace(classids,'C','')) from inserted;
if (@len=1)
begin
insert into tclasstree_report(reportid,classid)
select reportid,left(classids,len(classids)-1) from inserted;
end;
else if (@len=2)
begin
insert into tclasstree_report(reportid,classid)
select reportid,substring(classids,1,CHARINDEX(',',ClassIDs,1)-1) from inserted
union
select reportid,substring(classids,CHARINDEX(',',ClassIDs,1)+1,len(classids)-CHARINDEX(',',ClassIDs,1)-1) from inserted
end
else if (@len=3)
begin
insert into tclasstree_report(reportid,classid)
select  reportid,substring(classids,1,CHARINDEX(',',ClassIDs,1)-1) from inserted
union
select reportid,substring(classids,CHARINDEX(',',ClassIDs,1)+1,CHARINDEX(',',ClassIDs,CHARINDEX(',',ClassIDs,1)+1)-CHARINDEX(',',ClassIDs,1)-1) from inserted
union
select reportid,substring(classids,charindex(',',classids,CHARINDEX(',',classids,1)+1)+1,len(classids)-charindex(',',classids,CHARINDEX(',',classids,1)+1)-1) from inserted
end
else if (@len=4)
begin
insert into tclasstree_report(reportid,classid)
select reportid,substring(classids,1,CHARINDEX(',',ClassIDs,1)-1) from inserted
union
select reportid,substring(classids,CHARINDEX(',',ClassIDs,1)+1,CHARINDEX(',',ClassIDs,CHARINDEX(',',ClassIDs,1)+1)-CHARINDEX(',',ClassIDs,1)-1) from inserted
union
select reportid,substring(classids,charindex(',',classids,CHARINDEX(',',classids,1)+1)+1,
charindex(',',classids,charindex(',',classids,CHARINDEX(',',classids,1)+1)+1)-charindex(',',classids,CHARINDEX(',',classids,1)+1)-1) from inserted
union
select reportid,substring(classids,charindex(',',classids,charindex(',',classids,CHARINDEX(',',classids,1)+1)+1)+1,
len(classids)-charindex(',',classids,charind
a1fd
ex(',',classids,CHARINDEX(',',classids,1)+1)+1)-1) from inserted
end
end

后觉得此方法不妥,若栏目个数大于四个,则没法实现插入操作,且想要实现起来更加困难。于是就对其进行了改写,改写后不仅代码简化了很多,而且再多的栏目也能快速处理。具体实现如下:

alter trigger TRIG_TREPORT_TCLASSTREE
on tReport
for insert
as
begin
declare @s varchar(100);
select @s=classids from inserted;
while (charindex(',',@s)<>0)
begin
--第一个','之前的字符串
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,1,charindex(',',@s)-1) from inserted;
--将第一个','后面的字符串重新赋给@s
set @s=stuff(@s,1,charindex(',',@s),'')
--最后一个字符串
if (charindex(',',@s)=1)
begin
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,1,charindex(',',@s)-1) from inserted;
end
end
end
后来,需求再次变更,要求当treport表的classids字段根栏目为C732时,若只有两个栏目,则往tclasstree_report表插入两条数据;若classids有三个栏目,则跳过中间一个栏目,往tclasstree_report表插入第一个和第三个栏目。当treport表的classids字段根栏目不为C732时,插入规则和上面一样。

需求示例如下:

treport表数据如下:

ID              ReportID      ClassIDs

1132877 R5035181    C1000,

1132881 R5035173    C732,C113,C751,

1132882  R5035174    C732,C69,

1132883 R5035175    C732,C123,C124,

1132884 R5035176    C732,C139,C1143,

tclasstree_report表数据如下:

ID              ReportID     ClassID

7185280 R5035173   C732

7185282 R5035173   C751

7185283 R5035174   C732

7185284 R5035174   C69

7185285 R5035175   C732

7185287 R5035175   C124

7185288 R5035176   C732

7185290  R5035176   C1143

7185270  R5035181   C1000

实现如下:

alter trigger TRIG_TREPORT_TCLASSTREE
on TReport
for insert
as
begin
declare @s varchar(100);
select @s=classids from inserted;
if (CHARINDEX('C732',@s,1)=0)
begin
while (charindex(',',@s)<>0)
begin
--第一个','之前的字符串
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,1,charindex(',',@s)-1) from inserted;
--将第一个','后面的字符串重新赋给@s
set @s=stuff(@s,1,charindex(',',@s),'')
--最后一个字符串
if (charindex(',',@s)=1)
begin
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,1,charindex(',',@s)-1) from inserted;
end
end
end

else if (CHARINDEX('C732',@s,1)<>0)
begin
if (LEN(@s)-LEN(replace(@s,'C',''))=2)
begin
--第一个','之前的字符串
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,1,charindex(',',@s)-1) from inserted;
--将第一个','后面的字符串重新赋给@s
set @s=stuff(@s,1,charindex(',',@s),'')
--第二个字符串
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,1,charindex(',',@s)-1) from inserted;
end
else if (LEN(@s)-LEN(replace(@s,'C',''))=3)
begin
--第一个','之前的字符串
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,1,charindex(',',@s)-1) from inserted;
--第三个栏目
insert into tclasstree_report(reportid,classid)
select reportid,substring(@s,charindex(',',@s,CHARINDEX(',',@s,1)+1)+1,len(@s)-
charindex(',',@s,CHARINDEX(',',@s,1)+1)-1) from inserted;
end
end
end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: