Sql server的级联删除

      Javascript 2005-6-24 15:4

以前用Oracle数据库时发现在 On delete方面有个不方便的地方,即在Sql 脚本中指定 On Delete CasCade,运行之后,看foreignKey的属性,其On delete却不是Cascade,使用 oem、Toad、以及从系统中查询均是如此,但它的设置却已经生效。这个问题查了好多地方也没有查出来为什么。



这次用sql server,这个问题没有了,却出来另一个问题: 自引用不能设置 On delete(update)。

下面的脚本是在powerdesigner中生成的,在sql server中运行就出现问题了。




/*==============================================================*/
/* Table: departments */
/*==============================================================*/
create table departments (
departmentsID int not null,
dep_departmentsID int null,
departmentname varchar(60) null,
othersComment varchar(60) null,
constraint PK_DEPARTMENTS primary key (departmentsID)
)
go


alter table departments
add constraint FK_DEPARTME_REFERENCE_DEPARTME foreign key (dep_departmentsID)
references departments (departmentsID)
on delete cascade
go


在上面的表中,将某个表设置成自引用,将On delete设置成cascade,但是运行时提示:

将 FOREIGN KEY 约束 'FK_DEPARTME_REFERENCE_DEPARTME' 引入表 'departments' 中将导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其它 FOREIGN KEY 约束。

查看Sql server的文档,有如下说明:

由单个 DELETE 或 UPDATE 触发的一系列级联引用操作必须构成不包含循环引用的树。在 DELETE 或 UPDATE 所产生的所有级联引用操作的列表中,每个表只能出现一次。级联引用操作树到任何给定表的路径必须只有一个。树的任何分支在遇到指定了 NO ACTION 或默认为 NO ACTION 的表时终止。

从这个规定可以看出在sql server中,自引用不能设置级联,如果这样,上面的要求怎么实现呢?



一个比较容易想到的办法是 数据库中用触发器来实现 On delete cascade。但是这种方式实现起来的效率可能低一些。如下:


/*==============================================================*/
/* Table: departments */
/*==============================================================*/
create table departments (
departmentsID int not null,
dep_departmentsID int null,
departmentname varchar(60) null,
othersComment varchar(60) null,
constraint PK_DEPARTMENTS primary key (departmentsID)
)
go


alter table departments
add constraint FK_DEPARTME_REFERENCE_DEPARTME foreign key (dep_departmentsID)
references departments (departmentsID)

go

create trigger testdelete
on departments
INSTEAD OF delete
as
declare @id int
select @id=departmentsID from deleted
delete from departments where dep_departmentsID=@id
go
insert into departments (departmentsID,dep_departmentsID,departmentname)
values(1,null,'A局')
insert into departments (departmentsID,dep_departmentsID,departmentname)
values(2,null,'B局')
insert into departments (departmentsID,dep_departmentsID,departmentname)
values(3,1,'A局1处')
insert into departments (departmentsID,dep_departmentsID,departmentname)
values(4,1,'A局2处')
insert into departments (departmentsID,dep_departmentsID,departmentname)
values(5,1,'B局1处')

delete from departments where departmentsID=1
select * from departments
标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}