Recorrido de cursores dinámicos con DBMS_SQL

Es la primera vez que pido ayuda "by the web" y es porque estoy DESESPERADO!
No encuentro documentación necesaria para recorrer un cursor abierto de forma dinámica mediante el DBMS_SQL. PARSE, pues si bien si soy capaz de abrirlo (y cerrarlo), me es imposible recorrerlo y recoger la información en ningún tipo de variable...
Aunque tengo el cursor en un integer... ¿cómo recojo los datos de este cursor? No tengo forma de declarar una variable de tipo %rowtype ya que el cursor dinámico no me deja :¿-?
Todos los ejemplos del OAI Courseware (documentación oficial) son muy poco explícitos... Para ser más exactos se limitan a abrir un cursor y cerrarlo, y a decir que se recorre igual que un cursor normal.
Mi cogido genera una sentencia completa mediante una función F_SSQL() y es la que inicializa el cursor mediante el PARSE, pero como te comento no tengo forma de recorrer todas las tuplas que me devolvería la consulta completa (unos índices que me generarán múltiples tuplas en diferentes tablas de mi entidad-relación)... Te copy-paste el código
CREATE OR REPLACE PROCEDURE EMISION(
V NUMBER,
A NUMBER,
L NUMBER,
T NUMBER,
Comunidad number,
PERFIL NUMBER,
PERFIL_UNICO CHAR
) IS
TYPE TCursor IS REF CURSOR;
cur TCursor;
SSQL VARCHAR2(600);
d_id_com number;
d_id_pag number;
d_id_pda number;
BEGIN
DBMS_OUTPUT.ENABLE;
SSQL := F_SSQL(V,A,L,T,COMUNIDAD,PERFIL,PERFIL_UNICO);
DBMS_OUTPUT.PUT(SSQL); -- ESTO NO ME LO IMPRIME :-?
DBMS_SQL.OPEN_CURSOR(cur, SSQL,dbms_sql.native);
LOOP
FETCH cur INTO d_id_com, d_id_pag, d_id_pda;
IF cur%FOUND THEN
DBMS_SQL.PUT('' || TO_CHAR(d_id_com) || ', ' || TO_CHAR(d_id_pag) || ', ' || TO_CHAR(d_id_pda));
INSERT INTO T_FACTURAS VALUES (d_id_com, d_id_pag, 1, '01-01-01', 12, 1.12);
END IF;
EXIT WHEN cur%NOTFOUND;
END LOOP;
CLOSE cur;
END emision;
/
HELP ME!
THX

1 Respuesta

Respuesta
1
El problema es que estás cur como si fuera un cursor PL/SQL normal y DBMS_SQL coge como parámetro un entero y no cursor. Te envío codígo mío en el que se devuleven datos con DBMS_SQL. Echale un ojo a ver si te vale.
CREATE OR REPLACE FUNCTION busca_texto_en_long(sSchema varchar2,
STabla varchar2,
SColumna varchar2,
STexto varchar2
) RETURN varchar2
IS
cur_1 integer;
cur_2 integer;
buff varchar2(32767);
len integer;
offset integer;
v_length integer;
sentencia1 varchar2(500);
sentencia2 varchar2(500);
ret integer;
stmt varchar2(500);
LDKEY_TEMP number;
valor_a_devolver varchar2(2000);
sTab varchar2(20) := sTabla;
sCol varchar2(20) := sColumna;
BEGIN
-- En el caso de que vengan en blanco la tabla o la columna
-- le asignamos %, para que busque por todas las tablas o por
-- todas las columnas
if sTab = '' or sTab is null Then
sTab := '%';
end if;
if sCol = '' or sCol is null Then
sCol := '%';
end if;
sentencia1 := ' select LDKEY from ' || sSchema || '.' || 'LONGDESCRIPTION where LDOWNERTABLE like ' || '''' ||
sTab || '''' || ' and LDOWNERCOL like ' || '''' || sCol || '''';
cur_1 := dbms_sql.open_cursor;
dbms_sql.parse(cur_1,sentencia1,dbms_sql.NATIVE);
dbms_sql.define_column(cur_1,1,LDKEY_TEMP);
ret := dbms_sql.execute(cur_1);
loop
if dbms_sql.fetch_rows(cur_1) > 0 Then
dbms_sql.column_value(cur_1,1,LDKEY_TEMP);
sentencia2 := 'select LDTEXT from ' || sSchema || '.' || 'LONGDESCRIPTION' ||
' where LDKEY = ' || to_char(LDKEY_TEMP);
cur_2 := dbms_sql.open_cursor;
dbms_sql.parse(cur_2, sentencia2, dbms_sql.NATIVE);
dbms_sql.define_column_long(cur_2, 1);
ret := dbms_sql.execute(cur_2);
if (dbms_sql.fetch_rows(cur_2) > 0 ) then
offset := 1;
len := 0;
loop
dbms_sql.column_value_long(cur_2, 1,32767, offset, buff, v_length);
len := len + v_length;
exit when v_length < 32767;
offset := offset + v_length;
ret := instr(buff,0,sTexto);
if ret >= 0 Then -- La cadena que buscamos existe en la porcion del LONG
valor_a_devolver := valor_a_devolver || to_char(LDKEY_TEMP);
end if;
end loop;
end if;
dbms_sql.close_cursor(cur_2);
else
exit;
end if;
end loop;
return(valor_a_devolver);
end;

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas