Eu tenho um procedimento armazenado externo que está chamando um procedimento armazenado interno em um loop. O procedimento armazenado interno retorna um REF CURSOR
composto por 2 partes, (1) V_SUCCESSFUL_COUNT
(2) V_RESPONSE_CODE
.
Meu procedimento armazenado externo está coletando esses pares de todas as chamadas de procedimento armazenado interno nas matrizes correspondentes V_SUCCESSFUL_COUNTS
e V_RESPONSE_CODES
. Primeiro ele abre o cursor do procedimento armazenado interno, busca as duas partes em variáveis e depois adiciona essas variáveis aos arrays.
PROCEDURE OUTER_SP(PARAM1, .., P_REF_CURSOR REF CURSOR)
AS
..
V_SUCCESSFUL_COUNT NUMBER;
V_RESPONSE_CODE VARCHAR2(10);
V_SUCCESSFUL_COUNTS REF_TYPE_NUM_TABLE := REF_TYPE_NUM_TABLE(); /* Cumulative Successful Counts */
V_RESPONSE_CODES REF_VARCHAR2_ARRAY_TABLE := REF_VARCHAR2_ARRAY_TABLE(); /* Cumulative Response Codes */
V_REF_CURSOR SYS_REFCURSOR; /* Result from each inner SP */
FOR i IN 1 .. P_REF_ID_LIST.COUNT LOOP
SP_INNER(PARAM1,
PARAM2,
...
V_REF_CURSOR);
/* Add V_SUCCESSFUL_COUNT, V_RESPONSE_CODE outputs from this call to collections */
OPEN V_REF_CURSOR /* Error here! */;
FETCH V_REF_CURSOR INTO V_SUCCESSFUL_COUNT, V_RESPONSE_CODE;
V_SUCCESSFUL_COUNTS.EXTEND;
V_SUCCESSFUL_COUNTS(V_SUCCESSFUL_COUNTS.COUNT) := V_SUCCESSFUL_COUNT;
V_RESPONSE_CODES.EXTEND;
V_RESPONSE_CODES(V_RESPONSE_CODES.COUNT) := V_RESPONSE_CODE;
CLOSE V_REF_CURSOR /* Error here! */;
END LOOP;
Estou recebendo esse erro nas linhas
OPEN V_REF_CURSOR / CLOSE V_REF_CURSOR
enquanto tento recuperar o resultado de cada chamada de procedimento armazenado interno:
PLS-00382: a expressão é do tipo errado
Não gosto que eu abra o cursor do procedimento armazenado interno antes de chamar FETCH V_REF_CURSOR
.
Se eu remover essas linhas OPEN V_REF_CURSOR
/ CLOSE V_REF_CURSOR
e for direto para FETCH V_REF_CURSOR
, não haverá erro de sintaxe e o procedimento armazenado será compilado, mas os resultados adicionados ao array estarão incorretos ( NULL
), como posso ver quando executo esse procedimento armazenado externo.
Se você estiver usando um
SYS_REFCURSOR
tipo de dados, provavelmente já usouOPEN v_ref_cursor FOR ...
inSP_INNER
; nesse caso, é sintaticamente inválido tentarOPEN
o cursor novamente, pois ele já está aberto.Remova a
OPEN v_refcursor;
instrução (mas não aCLOSE
instrução) e o código parece funcionar:Então:
Saídas:
violino
Eu suspeito que
SP_INNER
não retorna nada.Aqui está uma demonstração que mostra como fazer isso (se tudo correr bem).
Esta é uma consulta que retorna alguns dados; é usado em
SP_INNER
:Meu
SP_INNER
procedimento é muito simples; a única coisa "importante" aqui é que a consulta usada para um cursor ref realmente retorna algo:Bloco PL/SQL anônimo que simula seu
OUTER_SP
:Como você pode ver, a saída reflete o que
select
a própria instrução retorna, então funciona .Como você não recebeu nada, verifique o
SP_INNER
que está acontecendo.Além disso,
for
o loop usaP_REF_ID_LIST.COUNT
, mas você nunca disse o quep_ref_id_list
é/contém. Se não houver nada lá, esse loop não será executado, então esse pode ser outro culpado. ExibaP_REF_ID_LIST.COUNT
o valor antes de usá-lo no loop para verificar seu valor.