这个问题困扰我很久了,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
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
如果主键/外键的关系是通过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
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
如果主键/外键的关系是通过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