--删除的存储过程
create proc p_delete
@id int --要删除的id
as
create table #t(id int,level int)
declare @l int
set @l=0
insert #t select @id,@l
while @@rowcount>0
begin
set @l=@l+1
insert #t select a.id,@l
from 表A a join #t b 
on a.pid=b.id and b.level=@l-1
end
set xact_abort on
begin tran
delete b 
from 表B b join #t d on b.id=d.id delete a
from 表A a join #t d on a.id=d.id
commit tran
go
--调用
exec p_delete 1

解决方案 »

  1.   

    --测试--测试数据
    create table 表A(Id int,PId int,textA varchar(10))
    insert 表A select 1,null,'t1'
    union  all select 2,null,'t2'
    union  all select 3,1,'t3'
    union  all select 4,1,'t4'
    union  all select 5,1,'t5'
    union  all select 6,3,'t6'
    union  all select 7,6,'t7'create table 表B(ID int,textB varchar(10))
    insert 表B select 1,'tb1'
    union  all select 2,'tb2'
    union  all select 3,'tb3'
    union  all select 4,'tb4'
    union  all select 5,'tb5'
    union  all select 5,'tb5_2'
    union  all select 6,'tb6'
    union  all select 6,'tb6_2'
    union  all select 7,'tb7'
    go--删除的存储过程
    create proc p_delete
    @id int --要删除的id
    as
    create table #t(id int,level int)
    declare @l int
    set @l=0
    insert #t select @id,@l
    while @@rowcount>0
    begin
    set @l=@l+1
    insert #t select a.id,@l
    from 表A a join #t b 
    on a.pid=b.id and b.level=@l-1
    end
    set xact_abort on
    begin tran
    delete b 
    from 表B b join #t d on b.id=d.id delete a
    from 表A a join #t d on a.id=d.id
    commit tran
    go--调用进行删除
    exec p_delete 1
    go--显示删除结果
    select * from 表A
    select * from 表b
    go--删除测试
    drop table 表A,表B
    drop proc p_delete/*--测试结果Id          PId         textA      
    ----------- ----------- ---------- 
    2           NULL        t2(所影响的行数为 1 行)
    ID          textB      
    ----------- ---------- 
    2           tb2(所影响的行数为 1 行)
    --*/
      

  2.   

    谢谢
    zheninchangjiang(徐震>愿母亲安息) 

    zjcxc(邹建) 
    再请问一下,这句话是什么意思?
    set xact_abort on
    谢谢
      

  3.   

    delete from a where id = 1 or pid = 1delete from b where 
    id not in(select id from a)
      

  4.   

    SET XACT_ABORT
    指定当 Transact-SQL 语句产生运行时错误时,Microsoft® SQL Server™ 是否自动回滚当前事务。
      

  5.   

    小弟有一个疑问,不太明白
    如果表A的ID和表A自身的PID建立关系了,

    delete a
    from 表A a join #t d on a.id=d.id
    不能完成,
    请问该怎么修改呢?
      

  6.   

    表A的ID和表A自身的PID建立关系了是什么意思?
      

  7.   

    declare @id int
    delete * from a,b where a.id=@id or a.pid=@id or b.id=@id
      

  8.   

    表A,
    Id     PId textA
    1       t1
    2 t2
    3 1 t3
    4 1 t4
    5 1 t5
    6 3 t6
    7 6 t7
    自身关系说明如下,ID 为主键,PID为副键,
    即,PID的值由ID的值决定,如PID=8,就不是一个合法的数据了。
    所以删除数据的时候,按照 邹建 大哥的方法时,
    就受到了关系的约束了。
    所以请问如果修改delete a
    from 表A a join #t d on a.id=d.id谢谢
      

  9.   

    真的不明白你的意思,pid=8不合法,是你自己处理的问题,不是我写的删除应该考虑的.我的删除只是把你指定的id及该id下的所有子id一并删除(注意是所有级别,不是只删除一级)而你的那个约束我更搞不清楚你在说什么?也不知道你的要求和楼主的要求有什么不同
      

  10.   

    我和楼主是同事,在解决同一个问题,楼主在先前描述的时候没有描述完全,漏了这一点,
    关系如下:关系 FK_表A_表A 主键表 表A(ID), 外部键表 表A,(PID)
    关系 FK_表A_表B 主键表 表A(ID), 外部键表 表B,(ID)在删除时,报错:
    Server: Msg 547, Level 16, State 1, Line 1
    DELETE statement conflicted with COLUMN SAME TABLE REFERENCE 
    constraint 'FK_表A_RELATION__表A'. The conflict occurred in database 'KWindows', table 'TCollection', column 'ParentID'.
    The statement has been terminated.
      

  11.   

    --测试--测试数据
    create table 表A(Id int primary key,
    PId int constraint FK_表A_RELATION__表A foreign key
    references 表A(Id) on update NO ACTION on delete NO ACTION,
    textA varchar(10))
    insert 表A select 1,null,'t1'
    union  all select 2,null,'t2'
    union  all select 3,1,'t3'
    union  all select 4,1,'t4'
    union  all select 5,1,'t5'
    union  all select 6,3,'t6'
    union  all select 7,6,'t7'create table 表B(ID int constraint FK_表B_RELATION__表A foreign key
    references 表A(Id) on update cascade on delete cascade,
    textB varchar(10))
    insert 表B select 1,'tb1'
    union  all select 2,'tb2'
    union  all select 3,'tb3'
    union  all select 4,'tb4'
    union  all select 5,'tb5'
    union  all select 5,'tb5_2'
    union  all select 6,'tb6'
    union  all select 6,'tb6_2'
    union  all select 7,'tb7'
    go--删除的存储过程
    create proc p_delete
    @id int --要删除的id
    as
    create table #t(id int,level int)
    declare @l int
    set @l=0
    insert #t select @id,@l
    while @@rowcount>0
    begin
    set @l=@l+1
    insert #t select a.id,@l
    from 表A a join #t b 
    on a.pid=b.id and b.level=@l-1
    end
    set xact_abort on
    begin tran
    delete b 
    from 表B b join #t d on b.id=d.id delete a
    from 表A a join #t d on a.id=d.id
    commit tran
    go--调用进行删除
    exec p_delete 1
    go--显示删除结果
    select * from 表A
    select * from 表b
    go--删除测试
    drop table 表B,表A
    drop proc p_delete/*--测试结果Id          PId         textA      
    ----------- ----------- ---------- 
    2           NULL        t2(所影响的行数为 1 行)
    ID          textB      
    ----------- ---------- 
    2           tb2(所影响的行数为 1 行)
    --*/