Procedure calculo_main(P_INI VARCHAR, P_FIM VARCHAR) IS
FLAG VARCHAR2(1):= 'N';
AUX1 NUMBER := 1;
BEGIN
OPEN PRINCIPAL(P_INI,P_FIM);
LOOP
FETCH PRINCIPAL INTO P_PROD_ACABADO;
EXIT WHEN PRINCIPAL%NOTFOUND;
OPEN SUBPRINCIPAL(P_PROD_ACABADO,P_PROD_ACABADO);
LOOP
EXIT WHEN SUBPRINCIPAL%NOTFOUND;
FETCH SUBPRINCIPAL INTO P_PROD_ACABADO,P_SUB_MP,P_DESCRIPTION,P_COMPONENT_QUANTITY,P_ITEM_TYPE;
IF CONDICAO
"FAZ CALCULOS"
ELSE
calculo_main(P_PROD_ACABADO, P_PROD_ACABADO);
END IF;
END LOOP;
CLOSE SUBPRINCIPAL;
END LOOP;
CLOSE PRINCIPAL;
END;
Caro Diego_mello, o problema não é esse...
Pois em procedure recursiva... eu preciso usar cursores Explicitos, com OPEN FETCH e CLOSE, o FOR já da erro de cara, por ser Cusros IMPLICITO..
Cara, indiferente ao erro que tu esta obtendo, já notou que dependendo como for sua estrutura de dados você podera entrar em loop infinito?
Se importaria em explicar qual seu objetivo, quem sabe assim possamos sugerir algo diferente.
Estou com algumas idéias aqui, tipo usar tabelas de memória, mas para saber qual se adequaria melhor precisaria saber do objetivo...
Procedure calculo_main(P_INI VARCHAR, P_FIM VARCHAR) IS
FLAG VARCHAR2(1):= 'N';
AUX1 NUMBER := 1;
BEGIN
OPEN PRINCIPAL(P_INI,P_FIM);
FETCH PRINCIPAL INTO P_PROD_ACABADO;
CLOSE PRINCIPAL;
IF (P_PROD_ACABADO IS NOT NULL) THEN
OPEN SUBPRINCIPAL(P_PROD_ACABADO,P_PROD_ACABADO);
FETCH SUBPRINCIPAL INTO P_PROD_ACABADO,P_SUB_MP,P_DESCRIPTION,P_COMPONENT_QUANTITY,P_ITEM_TYPE;
CLOSE SUBPRINCIPAL;
IF (P_PROD_ACABADO IS NOT NULL) THEN
IF CONDICAO THEN
"FAZ CALCULOS";
ELSE
calculo_main(P_PROD_ACABADO, P_PROD_ACABADO);
END IF;
END IF;
END IF;
END;
Pois é burga, pelo código original eu havia imaginado que na primeira chamada os parametros p_ini e p_fim são diferentes gerando um array de resultados desta forma até faria sentido este loop.
O que eu não entendi é o porque chamar a procedure novamente para os dados obtidos no cursor SUBPRINCIPAL. Eles viriam a ser diferentes do prod acabado principal será?
Bom a nós resta esperar um esclarecimento dos objetivos do procedimento para então sugestionar algo mais pontual...
SergioLBJr, o que ta estourando o erro é chamar a procedure dentro dela mesmo. Quando ele faz a chamada dentro do If ele ainda não resolvou todo o cursor da primeira chamada e tenta abri-lo novamente. Neste momento estoura o erro. Agora eu não entendo qual o objetivo desta recursividade...
A unica coisa que conseguo imaginar que possa estar acontecendo é que na tua segunda chamada da procedure ele ta tentando fzer o OPEN e enchergando que o cursor esta aberto (mesmo que seja na primeira chamada).
Pois é burga, pelo código original eu havia imaginado que na primeira chamada os parametros p_ini e p_fim são diferentes gerando um array de resultados desta forma até faria sentido este loop.
Então, pelo código, eu acredito que não gere um array de resultados, senão de duas uma, ou o FECTH retornaria uma exceção (considerando P_PROD_ACABADO como do tipo VARCHAR), ou a chamada na recursão daria exeção (considerando P_PROD_ACABADO como um array), pois o tipo do parâmetro do procedimento não é um array.
Caros Amigos, Quando passo o o P_INI e P_FIM, o primeiro Loop me retorna uma lista de componetes... P_PROD_ACABADO
No segundo LOOP, eu passo cada Componente, para que retorne os SUB_COMPONETES... caso retorne uma peça Ele Calcula na condição "Faz calculos", Se não retornar peça e sim retornar componente ele precisa vafer a recursividade até chegar numa peça pra CALCULO,
é por isso que não vai entrar em LOOP enfinito, porque no final é sempre uma peça.
O Meus Cursores estou declarando dentro da PACKEGE.
Agora não sei o que pode estar dando erro, pois fiz teste, e ele estoura quando faz a segunda chamada da calculo_main.
SQL> SELECT pai
2 ,filho
3 ,peca
4 ,DECODE(peca, 'S', 'CALCULA!') calculo
5 FROM (
6 --/ Sua tabela recursiva...
7 SELECT 1 pai, 2 filho, 'N' peca FROM dual UNION
8 SELECT 2 pai, 3 filho, 'N' peca FROM dual UNION
9 SELECT 3 pai, 4 filho, 'N' peca FROM dual UNION
10 SELECT 4 pai, 5 filho, 'S' peca FROM dual
11 )
12 CONNECT BY PRIOR filho = pai
13 START WITH pai = 1;
PAI FILHO PECA CALCULO
---------- ---------- ---- --------
1 2 N
2 3 N
3 4 N
4 5 S CALCULA!
MEU DEUS....quantas tentativas....
estava a 2 dias nisso....
POR INCRIVEL QUE PAREÇA, a dica do nosso amigo SergioLBJr de criar o cursor dentro da PROCEDURE...
Eu tive muito pouco contato com recursividade, mas sempre que utilizei declarei os cursores dentro das procedures, por isso nunca me deparei com esse tipo de erro.
Mas se fomos parar pra pensar isso é bem lógico, uma vez que o cursor for declarado de novo ele deve ser considerado com um novo cursor, e como o seu estava na package ele era considerado como sendo o mesmo.
E o no seu procedimento você não podia fechalo pois chamava a procedure recursiva no meio do loop, logo acusava que ainda estava aberto.