试了一下,果然和楼主说的一样.如果为外键设置了级联更新(ON UPDATE CASCADE),那么DELETE触发器被触发时就会导致外键约束错误.
如果楼主要使用触发器来解决的话,请试试:
if object_id('tri_delete') is not null
drop trigger tri_delete
if object_id('tri_update') is not null
drop trigger tri_update
go
----创建DELETE触发器
create trigger tri_delete
on employee
for delete
as
UPDATE a set employenumber = null
FROM house a,deleted d
WHERE a.employenumber = d.number
go
----创建UPDATE触发器.当employee表中没有IDENTITY标识列时,请使用此触发器
create trigger tri_update
on employee
for update
as
if @@rowcount = 1 /*如果只更新了一行(必须在触发器第一行判断@@rowcount)*/
UPDATE a set a.employenumber = i.number
FROM house a,deleted d,inserted i
WHERE a.employenumber = d.number
else /*如果更新了多行*/
begin
if object_id('tempdb..#tmp1') is not null
drop table #tmp1
if object_id('tempdb..#tmp2') is not null
drop table #tmp2
----为inserted表和deleted表生成用于行一一对应的id
select id = identity(int,1,1),number into #tmp1 from inserted
select id = identity(int,1,1),number into #tmp2 from deleted
----更新'外键列'
UPDATE a set a.employenumber = i.number
FROM house a, #tmp2 d, #tmp1 i
WHERE a.employenumber = d.number and d.id = i.id
----清除临时表
drop table #tmp1
drop table #tmp2
end
go
----如果employee表中有IDENTITY列,假设名称为id,则使用此UPDATE触发器
create trigger tri_update
on employee
for update
as
UPDATE a set a.employenumber = i.number
FROM house a,deleted d,inserted i
WHERE a.employenumber = d.number and d.id = i.id
create trigger tri_delete
on employee
for update
as
UPDATE a set employenumber = 这个值怎么写?(我试inserted.number但无效)
FROM house a,deleted d
WHERE a.employenumber = d.number
如果主键表的主键更新,外键表的外键也同步更新的话,应该设置该外键为级联更新,这样主键列更新时,外键列自动会同步更新,这种更新是由SQLSERVER来完成的,多省事.例如楼主修改employee.number时,house.employenumber也跟着更新.
至于主键列的值被删除时,SQLSERVER2000没有将外键列自动设为NULL的功能,只能通过在主键表创建DELETE触发器来模拟"自动"设为NULL.假设主键表为employee,外键表为house,触发器为:
create trigger tri_delete
on employee
for delete
as
begin transaction
UPDATE a set employenumber = NULL
FROM house a,deleted d --被删除的主键列都在deleted表中
WHERE a.employenumber = d.number
if @@error > 0
begin
raiserror('Can not update foreign key!',16,1)
rollback
end
commit
go