ao usuario. Ele somente recebe os parametros, e chama o procedimento de explosao da estrutura, chamado spcAdhExpEst (procedimento recursivo). Code Snippet CREATE proc spcAdhExplodeProduto @cd_item char(13) as /* Autor: Fabiano Cores Data : 23/12/2010 Site : http://sqlburger.blogspot.com Desenvolvido para demonstrar a utilizacao de procedimentos recursivos no SQL Server. A reproducao deste artigo so e permitida se forem mantidos os creditos do autor. */ -- Esta tabela possui papel fundamental na recursividade. Esta -- tabela ira existir durante toda a execucao deste procedimento -- mesmo quando chamamos executamos um segundo procedimento. create table #retorno ( cd_componente char(18) collate database_default null , qt_aplicada decimal(10,4) null , nivel smallint null , ordem int not null identity) -- Insiro o item pai, para que o usuario saiba de qual produto -- esta tirando o relatorio insert into #retorno (cd_componente, qt_aplicada, nivel) select @cd_item, 1, 1 -- Este e o procedimento recursivo. Ele fara referencia a ele -- mesmo, enquanto preenche a tabela #retorno exec spcAdhExpEst @cd_item -- Aqui, eu pego os registros da tabela #retorno, e retorno -- ao software .NET, para exibicao ao usuario. select convert(char(18), space((nivel-1) * 2) + a.cd_Componente) as 'Codigo' , convert(char(65), space((nivel-1) * 2) + b.descricao) as 'Descricao' , a.qt_aplicada 'Quantidade' , a.nivel -1 as 'Nivel' from #retorno a, item b where a.cd_componente = b.cd_item order by a.ordem -- Este e o codigo do procedimento recursivo. Ele insere na tabela #retorno, que foi criada pelo seu procedimento antecessor (spcAdhExplodeEstrutura), e faz referencia a si mesma: Code Snippet -- CREATE proc spcAdhExpEst @cd_item char(13) as /* Autor: Fabiano Cores Data : 23/12/2010 Site : http://sqlburger.blogspot.com Desenvolvido para demonstrar a utilizacao de procedimentos recursivos no SQL Server. A reproducao deste artigo so e permitida se forem mantidos os creditos do autor. */ declare @vcd_componente char(13) declare @vqt_aplicada decimal(19,4) -- Insere os componentes simples (nao possuem estrutura abaixo) insert into #retorno (cd_componente, qt_aplicada, nivel) select a.cd_componente, a.qt_aplicada, @@nestlevel from processoitem a, item b where a.cd_item = @cd_item and a.cd_componente = b.cd_item and not exists (select 0 from processoitem c where c.cd_item = a.cd_componente) order by b.descricao -- Aqui e montado um cursor nos itens complexos (que possuem -- estrutura). E utilizado um cursor por que para cada item -- que possui estrutura, eu vou fazer a chamada recursiva. declare c1 cursor local fast_forward read_only for select a.cd_componente, a.qt_aplicada from processoitem a, item b where a.cd_item = @cd_item and a.cd_componente = b.cd_item and exists (select 0 from processoitem c where c.cd_item = a.cd_componente) order by b.descricao open c1 while 1 = 1 begin fetch next from c1 into @vcd_componente, @vqt_aplicada if @@fetch_status <> 0 break insert into #retorno (cd_componente, qt_aplicada, nivel) select @vcd_componente, @vqt_aplicada, @@nestlevel -- Chamada recursiva (executando ele mesmo) exec spcAdhExpEst @vcd_componente end close c1 deallocate c1 -- Detalhes importantes que devem ser observados: 1. A tabela temporaria foi criada no primeiro procedimento. Se ela fosse criada no procedimento recursivo, daria erro, pois ele tentaria criar mais de uma vez a mesma tabela, desta forma, ela sendo criada apenas uma vez pelo procedimento pai, nao havera problemas. 2. O procedimento filho (spcAdhExpEst) consegue