--建立函數
Create Function F_GetChildren(@id Varchar(10))
Returns @Tree Table (id Varchar(10), pid Varchar(10))
As
Begin
Insert @Tree Select id, pid From 表 Where id = @id
While @@Rowcount > 0
Insert @Tree Select A.id, A.pid From 表 A Inner Join @Tree B On A.pid = B.id And A.id Not In (Select id From @Tree)
Return
End
GO
--測試
Delete From 表 Where ID In (Select id From dbo.F_GetChildren('01'))Select * From 表

解决方案 »

  1.   

    --建立測試環境
    Create Table 表
    (id Varchar(10),
    name Nvarchar(10),
    pid Varchar(10)
    )
    Insert 表 Select '01', N'张三', '00'
    Union All Select '02', N'李四', '00'
    Union All Select '03', N'王五', '01'
    Union All Select '04', N'牛六', '02'
    Union All Select '05', N'马七', '04'
    Union All Select '06', N'张八', '03'
    GO
    --建立函數
    Create Function F_GetChildren(@id Varchar(10))
    Returns @Tree Table (id Varchar(10), pid Varchar(10))
    As
    Begin
    Insert @Tree Select id, pid From 表 Where id = @id
    While @@Rowcount > 0
    Insert @Tree Select A.id, A.pid From 表 A Inner Join @Tree B On A.pid = B.id And A.id Not In (Select id From @Tree)
    Return
    End
    GO
    --測試
    Delete From 表 Where ID In (Select id From dbo.F_GetChildren('01'))Select * From 表
    GO
    --刪除測試環境
    Drop Table 表
    Drop Function F_GetChildren
    --結果
    /*
    id name pid
    02 李四 00
    04 牛六 02
    05 马七 04
    */
      

  2.   

    tbxl(攻城者) 、mengmou()mengmou() 你们两个怎么了,问题不解决结什么贴阿?
      

  3.   

    Love001(随风飞) ( ) 信誉:100  2007-08-17 14:48:42  得分: 0  
     
     
       不创建函数可以么?
      
     
    ----------------
    你的子節點的層數是不是固定的,如果是固定的,可以不用函數,如果不是,只能使用函數了路。
      

  4.   

    mengmou()mengmou() ,tbxl(攻城者) 別搗亂。 :)
      

  5.   

    Love001(随风飞) ( ) 信誉:100  2007-08-17 15:00:37  得分: 0  
     
     
       触发器可以么?--------可以,但是有限制。SQL Server 2000中触发器嵌套的最大层数为32层。
      

  6.   

    --经过测试,触发器可以实现,代码如下
    if exists(select name from sysobjects where name='test'and type='U')
    drop table [dbo].[test]
    go
    create table [dbo].[test](id char(10),name char(20),pid char(10))
    go
    insert into test
    select'00','aaa','00'
    union all select'01','aaa','00'
    union all select'02','aaa','00'
    union all select'03','aaa','01'
    union all select'04','aaa','01'
    union all select'05','aaa','02'
    union all select'06','aaa','02'
    union all select'07','aaa','04'
    union all select'08','aaa','04'
    union all select'09','aaa','05'
    union all select'10','aaa','05'
    go
    if exists(select name from sysobjects where name='tg_test'and type='TR')
    drop trigger [dbo].[tg_test] 
    go
    create trigger [dbo].[tg_test] 
    on [dbo].[test] 
    after delete
    as
    begin 
    if exists(select 1 from test where pid in(select id from deleted ))
    delete from test where pid in(select id from deleted )
    end
    goselect*from [dbo].[test] delete from [dbo].[test] where id='02'select*from [dbo].[test]  
    /*结果
    id         name                 pid
    ---------- -------------------- ----------
    00         aaa                  00        
    01         aaa                  00        
    03         aaa                  01        
    04         aaa                  01        
    07         aaa                  04        
    08         aaa                  04        
    09         aaa                  05        
    10         aaa                  05     
    */
      

  7.   

    用INSTEAD OF DELETE 触发器
      

  8.   

    上面的那个测试,记得要把数据库的Recursive Triggers(递归触发器) 设为 TRUE
      

  9.   

    用鱼的表
    paoluo(一天到晚游泳的鱼) ( ) 信誉:100 建立一个触发器
    CREATE TRIGGER [Ttt] ON [dbo].[表] 
    INSTEAD OF DELETE 
    AS
    declare
    @id int
    declare @Tree Table (id Varchar(10), pid Varchar(10))Insert @Tree Select id, pid From 表 where id=(select id from deleted)
    While @@Rowcount > 0
    Insert @Tree Select A.id, A.pid From 表 A Inner Join @Tree B On A.pid = B.id And A.id Not In (Select id From @Tree)
    Delete From 表 Where ID In (select id from @tree)
      

  10.   

    --要设置允许递归触发才行:   
    alter   database   你的库名   set   RECURSIVE_TRIGGERS   ON   
    RECURSIVE_TRIGGERS   ON   |   OFF   
    如果指定为   ON,将允许递归激发触发器。RECURSIVE_TRIGGERS   OFF(默认值)只禁止直接递归。若要也禁用间接递归,请使用   sp_configure   将   nested   triggers   服务器选项设置为   0。
      

  11.   

    brother2605(幽灵) ( ) 信誉:100 好像有问题,删除01的应该把07 08 也删除掉,但是没被删除
      

  12.   

    那是他測試的時候,沒有設置RECURSIVE_TRIGGERS
      

  13.   

    這是我測試的代碼--建立測試環境
    Create Table 表
    (id Varchar(10),
    name Nvarchar(10),
    pid Varchar(10)
    )
    Insert 表 Select '01', N'张三', '00'
    Union All Select '02', N'李四', '00'
    Union All Select '03', N'王五', '01'
    Union All Select '04', N'牛六', '02'
    Union All Select '05', N'马七', '04'
    Union All Select '06', N'张八', '03'
    GO
    --建立觸發器
    Create Trigger Delete_Trigger On 表
    For Delete
    As
    If Exists(Select 1 From 表 Where pid in(Select id From Deleted))
    Delete From 表 Where pid In (Select id From Deleted)
    GO
    --測試
    Alter Database TEST Set RECURSIVE_TRIGGERS ON
     
    Delete From 表 Where ID = '01'Select * From 表Alter Database TEST Set RECURSIVE_TRIGGERS OFF
    GO
    --刪除測試環境
    Drop Table 表
    --結果
    /*
    id name pid
    02 李四 00
    04 牛六 02
    05 马七 04
    */
      

  14.   

    tracyLD() ,你直接刪除看看.
      

  15.   

    tracyLD() ( ) 信誉:100  2007-08-17 17:16:05  得分: 0  
     
     
       楼主,最后一条“06 张八 03”要删除吗?----------"如何写delete语句,删除id=‘01’,同时把‘01’的所有子孙节点完全删除"重點,“所有子孙节点完全删除”
      

  16.   

    delete from 表 where pid='01' 
    or id in 
    (select id from 表 where (select name from 表 where id='01') like '%' +convert(char(2),name) +'%')刚才一直发不了回复。郁闷
      

  17.   

    paoluo(一天到晚游泳的鱼),你试试我的方法能删除吧。
      

  18.   

    Love001(随风飞),你要的是这个结果吧。
      

  19.   

    tracyLD() ( ) 信誉:100  2007-08-17 17:44:11  得分: 0  
     
     
       paoluo(一天到晚游泳的鱼),你试试我的方法能删除吧。
      
     tracyLD() ( ) 信誉:100  2007-08-17 17:44:48  得分: 0  
     
     
       Love001(随风飞),你要的是这个结果吧。
      
    -----------------當然不是,你自己可以測試看看
      

  20.   

    paoluo(一天到晚游泳的鱼) ( ) 信誉:100 
    你说哪里不是?我测试过的。
      

  21.   

    你的語句的結果/*
    id name pid
    01 张三 00
    02 李四 00
    04 牛六 02
    05 马七 04
    06 张八 03
    */和樓主的結果完全不一樣
      

  22.   

    to tracyLD():
    你现在可能还没明白树是怎么回事吧,比如你把一颗树上的一个树干砍下来了,是不是他后面所带的所有的枝叶都下来了,这是一个递归的问题,当删除父结点O时,相对于它的子结点A,B来说,都要被删除的,那么同理,当A或者B要被删除时,那么它的子结点也要删除,依次类推,直到最后的那个最底层的节点或叶子为止。而你的那个语句,也仅仅只是删除了一层子结点而已。
      

  23.   

    谢谢大家支持,可是无论函数、触发器都不是我想要的。用select可以实现么?
      

  24.   

    Love001(随风飞) ( ) 信誉:100  2007-08-21 08:15:38  得分: 0  
     
     
       谢谢大家支持,可是无论函数、触发器都不是我想要的。用select可以实现么?
      
    ------------------如果你的子節點的層數是固定的,只用select可以。但是不是固定的,要麼使用函數,要麼使用觸發器。
      

  25.   

    谢谢,paoluo,假设层数是固定的,如何写?
      

  26.   

    如何写delete语句,删除id=‘01’,同时把‘01’的所有子孙节点完全删除
    例如:我删除id=‘01’后,表记录为
    表:
    idnamepid
    02李四00
    04牛六02
    05马七04
    delete from table where id like '01%' or id like '%01'注:如上删除语句只有当id 为char(n) ,即等长 数据 ,希望可以解决问题
      

  27.   

    Love001(随风飞) ( ) 信誉:100  2007-8-21 9:17:24  得分: 0  
     
     
       
    谢谢,paoluo,假设层数是固定的,如何写?--------你的層數是固定幾層的?最好不要過多,不然語句會很複雜。
      

  28.   

    1、先建一个临时表:临时表
    if exists (select  *  from 临时表)
            drop table 临时表
    select * into 临时表 from 表 where id='01'2、建一个存储过程或者在查询分析器中执行以下语句
    while  exists (select  *  from 表 where pid in (select  id  from 临时表 )  and  id  not  in  ( select  id  from  临时表 ) )
    insert into 临时表 select * from 表 where pid in (select id from 临时表) and id not in (select id from 临时表)3、执行查询语句
    select * from 表 where id not in (select id from 临时表)4、删除临时表
    drop table 临时表
      

  29.   

    Love001(随风飞) ( ) 信誉:100  2007-8-22 8:05:39  得分: 0  
     
     
       
    就如上6条记录--------
    可以這麼寫Delete From 表 Where ID In 
    (Select '01' As id
    Union All
    Select id From 表 Where pid = '01'
    Union All
    Select A.id From 表 A Inner Join 表 B On A.pid = B.id Where B.pid = '01'
    )
      

  30.   


    --建立測試環境
    Create Table 表
    (id Varchar(10),
    name Nvarchar(10),
    pid Varchar(10)
    )
    Insert 表 Select '01',N'张三','00'
    Union All Select '02',N'李四','00'
    Union All Select '03',N'王五','01'
    Union All Select '04',N'牛六','02'
    Union All Select '05',N'马七','04'
    Union All Select '06',N'张八','03'
    GO
    --測試
    Delete From 表 Where ID In 
    (Select '01' As id
    Union All
    Select id From 表 Where pid = '01'
    Union All
    Select A.id From 表 A Inner Join 表 B On A.pid = B.id Where B.pid = '01'
    )Select * From 表
    GO
    --刪除測試環境
    Drop Table 表
    --結果
    /*
    id name pid
    02 李四 00
    04 牛六 02
    05 马七 04
    */