日期:2014-05-18  浏览次数:20555 次

要在存储过程中同时用递归和循环,怎么写?
ATO主表 结构如下
主键ID PID
  1 1001
  2 1002
  3 1003
  4 0007

ATO从表 结构如下
主键ID ATOID PID
 1 1 0003
 2 1 0004
 3 1 0005
 4 1 0007
 5 2 0008
 6 2 0009
 7 3 0007
 8 3 0009
 9 4 0010
 10 4 0011

其中,从表的ATOID等于主表中的主键ID。PID是零件ID,而有些组装零件,也是由零件构成的。也就是说,从表体现的是主表零件的组成零件。

我需要实现的功能如下:
已知参数是ATOID。
先根据ATOID在从表中查询出该ATOID对应的零件,再根据查询出的零件,去主表中查询是否存在,若存在,再往从表里查询子零件。
例子:
已知ATOID为1,先找到从表中1对应的PID有0003,0004,0005,0007。
根据PID一个个去主表里查询,得0003,0004,0005在主表中都不存在。0007在主表中存在,对应的ATOID为4。
在从表中查询ATOID为4的零件,有0010和0011。
所以最终获得的PID应该是0003,0004,0005,0010,0011
(例子中仅仅是2层,事实上可能更更多层。)
这样,有循环,又有递归。写了好一会,始终不对啊。请各位帮忙试试看。

------解决方案--------------------
SQL code
這樣?

use Tempdb
go
--> --> 
 
if not object_id(N'A') is null
    drop table A
Go
Create table A([ID] int,[PID] nvarchar(4))
Insert A
select 1,N'1001' union all
select 2,N'1002' union all
select 3,N'1003' union all
select 4,N'0007'
Go

--> --> 
 
if not object_id(N'B') is null
    drop table B
Go
Create table B([ID] int,[ATOID] int,[PID] nvarchar(4))
Insert B
select 1,1,N'0003' union all
select 2,1,N'0004' union all
select 3,1,N'0005' union all
select 4,1,N'0007' union all
select 5,2,N'0008' union all
select 6,2,N'0009' union all
select 7,3,N'0007' union all
select 8,3,N'0009' union all
select 9,4,N'0010' union all
select 10,4,N'0011'
Go
CREATE PROCEDURE pA(@ATOID int)
AS
;WITH C
AS
(
Select * from B WHERE [ATOID]=@ATOID
UNION ALL
SELECT b.* FROM C AS a INNER JOIN B ON a.[ID]=b.[ATOID] INNER JOIN A AS c ON a.PID=c.[PID]
)
SELECT * FROM C  AS a WHERE NOT EXISTS(SELECT 1 FROM C WHERE [ATOID]=a.ID)
go

EXEC pA 1
/*
ID    ATOID    PID
2    1    0004
3    1    0005
9    4    0010
10    4    0011
*/