请教一个关于触发器的问题

时间:2020-12-11 05:01:01
有表A,B,我现在A上键触发器,要求当A的主键被更新时,同时更新B表中相应字段。
这个问题困扰我很久了,SQL SERVER 中不象ORACLE中可以逐行更新,那如果我对A表进行批量更新时,我该如何去更新B表中相应的数据呢?

9 个解决方案

#1


不用建立触发器,设置级联更新即可。
在企业管理器里设计表,选择关系。

#2


方法一:建立关系,设置及联更新
方法二:触发器中使用游标

#3


级联更新呆会去试试。触发器中建游标该如何实现呢,分别对INSERTED表和DELETED表建吗,如何能确定那些字段能一一对应上呢?

#4


首选级联更新
用触发器也行
根本不要用游标的

#5


test:

create table t_Test070109a
(
  aid int ,
  bid int
)

create table t_Test070109b
(
  cid int ,
  did int
)

insert into t_Test070109a
select 1 , 2 union
select 2 , 3 union
select 1 , 3

insert into t_Test070109b
select 2 , 1 union
select 2 , 3 union
select 3 , 3 union
select 3 , 5 union
select 8 , 0 


create trigger udt_t_Test070109au
on    t_Test070109a
for   update
as
  begin 
    update t_Test070109b
    set    did = 1
    from   deleted a , t_Test070109b b
    where  a.bid = b.cid

    if @@error <> 0  raiserror('update error!' , 16 , 1 )
   
   end

--
select * from t_Test070109a
select * from t_Test070109b

---
begin tran 
update t_Test070109a
set    bid = 2
where  aid = 1

select * from t_Test070109a
select * from t_Test070109b
rollback tran

#6


用级联更新方便得要死,楼主干嘛要走弯路哟

#7


级联更新不就行了吗

#8


不过好像SQL SERVER 2000以前的版本不支持主键的级联更新和删除,要想完成这样的功能只能用触发器了

#9


以下内容适用于SQL SERVER 2000以前的版本,SQL SERVER 2000及其以后的版本用cascade关键字定义参照完成性约束可以解决级联更新问题:

如果主键/外键的关系是通过SQL SERVER的参照完整性约束定义的话,是不能用触发器实现级联更新或删除的,因为SQL SERVER事务执行的顺序中,约束检查将会先于触发器执行,这样的话,更新主键的时候参照完整性约束将会阻止其更新,而级联更新的触发器将不会执行。在这种情况下只能在存储过程中完成级联更新,更新时可以先在主表中插入新的主键的行,然后把要更新的那些行的其他新内容都复制到新行中,接着更新从表中的外键位新的主键,最后删除旧的那些主键行就好了。

如果主键/外键之间没有SQL SERVER的参照完整性约束定义,可以使用下面的触发器进行级联更新:


CREATE TRIGGER [cascade] ON [a] 
FOR UPDATE 
AS
if update(a_id)
begin
if @@rowcount = 1
begin
update b set b.a_id = inserted.a_id  from inserted,b join deleted on b.a_id = deleted.a_id
end
else
begin
rollback transaction
print 'Multi-row update on table "titles" not allowed.'
end
end

#1


不用建立触发器,设置级联更新即可。
在企业管理器里设计表,选择关系。

#2


方法一:建立关系,设置及联更新
方法二:触发器中使用游标

#3


级联更新呆会去试试。触发器中建游标该如何实现呢,分别对INSERTED表和DELETED表建吗,如何能确定那些字段能一一对应上呢?

#4


首选级联更新
用触发器也行
根本不要用游标的

#5


test:

create table t_Test070109a
(
  aid int ,
  bid int
)

create table t_Test070109b
(
  cid int ,
  did int
)

insert into t_Test070109a
select 1 , 2 union
select 2 , 3 union
select 1 , 3

insert into t_Test070109b
select 2 , 1 union
select 2 , 3 union
select 3 , 3 union
select 3 , 5 union
select 8 , 0 


create trigger udt_t_Test070109au
on    t_Test070109a
for   update
as
  begin 
    update t_Test070109b
    set    did = 1
    from   deleted a , t_Test070109b b
    where  a.bid = b.cid

    if @@error <> 0  raiserror('update error!' , 16 , 1 )
   
   end

--
select * from t_Test070109a
select * from t_Test070109b

---
begin tran 
update t_Test070109a
set    bid = 2
where  aid = 1

select * from t_Test070109a
select * from t_Test070109b
rollback tran

#6


用级联更新方便得要死,楼主干嘛要走弯路哟

#7


级联更新不就行了吗

#8


不过好像SQL SERVER 2000以前的版本不支持主键的级联更新和删除,要想完成这样的功能只能用触发器了

#9


以下内容适用于SQL SERVER 2000以前的版本,SQL SERVER 2000及其以后的版本用cascade关键字定义参照完成性约束可以解决级联更新问题:

如果主键/外键的关系是通过SQL SERVER的参照完整性约束定义的话,是不能用触发器实现级联更新或删除的,因为SQL SERVER事务执行的顺序中,约束检查将会先于触发器执行,这样的话,更新主键的时候参照完整性约束将会阻止其更新,而级联更新的触发器将不会执行。在这种情况下只能在存储过程中完成级联更新,更新时可以先在主表中插入新的主键的行,然后把要更新的那些行的其他新内容都复制到新行中,接着更新从表中的外键位新的主键,最后删除旧的那些主键行就好了。

如果主键/外键之间没有SQL SERVER的参照完整性约束定义,可以使用下面的触发器进行级联更新:


CREATE TRIGGER [cascade] ON [a] 
FOR UPDATE 
AS
if update(a_id)
begin
if @@rowcount = 1
begin
update b set b.a_id = inserted.a_id  from inserted,b join deleted on b.a_id = deleted.a_id
end
else
begin
rollback transaction
print 'Multi-row update on table "titles" not allowed.'
end
end