CURSOR II: ROWSET
Vamos a mostrar otra manera de recuperar registros de un cursor.
Partimos de una rutina que realiza un CURSOR a una tabla para recuperar todos los registros que cumplan una determinada condición.
Nuestra rutina devolverá la información recuperada al programa llamante a través de una tabla de 10 ocurrencias definida en la linkage.
Vamos con el ejemplo:
Imaginemos que la tabla a la que queremos acceder tiene estos datos:
Siendo CAMPO1 la clave.
En esta versión del uso de cursores mostraremos el uso de la sentencia ROWSET para recuperar los datos.
Trabajaremos con un cursor ROWSET POSITIONING. Este
tipo de cursor nos permite recuperar uno o más registros en un solo FETCH.
Definimos un cursor del siguiente modo:
WORKING-STORAGE SECTION.
EXEC SQL
DECLARE CURSOR CUR_TABLA ROWSET POSITIONING FOR
SELECT CAMPO1,
CAMPO2,
CAMPO3,
CAMPO4,
CAMPO5
FROM TABLA1
WHERE CAMPO1 = :CLAVE-CAMPO1
ORDER BY CAMPO1
END-EXEC
01 TBL-FETCH.
05 TBL-CAMPO1 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO2 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO3 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO4 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO5 PIC XX OCCURS 100 TIMES.
01 HNUM-REGS PIC S9(9) COMP.
IMPORTANTE: La variable HNUM-REGS sera la variable HOST que indicará al FETCH cuantos registros queremos recuperar.
Esta variable tiene que ser binaria (tipo COMP) y además debe estar definida en el nivel de working 01.
En la linkage recibiremos la información de los campos clave.
LINKAGE SECTION.
01 ENTRADA.
05 NUM-REGISTROS PIC 9(4).
05 ENT-CAMPO1 PIC XX.
01 SALIDA.
05 SAL-DATOS OCCURS 10 TIMES.
10 SAL-CAMPO1 PIC XX.
10 SAL-CAMPO2 PIC XX.
10 SAL-CAMPO3 PIC XX.
10 SAL-CAMPO4 PIC XX.
10 SAL-CAMPO5 PIC XX.
En el inicio del programa informamos las variables de acceso al WHERE y realizaremos el OPEN del cursor:
INICIO
IF ENT-CAMPO1 EQUAL SPACES OR LOW-VALUES
DISPLAY 'LA CLAVE ESTA VACIA'
PERFORM 90000-FINAL
END-IF
MOVE ENT-CAMPO1 TO CLAVE-CAMPO1
Si no informa la variable número de registros la informamos con el número máximo de ocurrencias, en este caso 10.
IF NUM-REGISTROS EQUAL ZEROS OR LOW-VALUES
MOVE 10 TO HNUM-REGS
ELSE
MOVE NUM-REGISTROS TO HNUM-REGS
END-IF
EXEC SQL
OPEN CUR_TABLA
END-EXEC
Controlaremos el SQLCODE. Si no fuese cero, tendríamos que dar un error.
IF SQLCODE NOT EQUAL ZEROES
DISPLAY 'ERROR EN EL OPEN CURSOR. EL SQLCODE ES: 'SQLCODE
PERFORM 90000-FINAL
END-IF
En el proceso realizamos un FECTH para recuperar todos los registros marcados por la variable de entrada NUM-REGISTROS(HNUM-REGS) en una tabla interna(TBL-FETCH).
A continuación volcamos la información de nuestra tabla interna en la tabla de salida:
PROCESO
EXEC SQL
FETCH NEXT ROWSET CUR_TABLA FOR :HNUM-REGS ROWS
INTO :TBL-CAMPO1,
:TBL-CAMPO2,
:TBL-CAMPO3,
:TBL-CAMPO4,
:TBL-CAMPO5
END-EXEC
Controlamos el SQLCODE devuelto:
EVALUATE TRUE
WHEN SQLCODE EQUAL ZEROES
DISPLAY 'TODO EN ORDEN'
WHEN SQLCODE EQUAL +100 AND SQLERRD(3) > 0
DISPLAY 'TODO EN ORDEN'
WHEN SQLCODE EQUAL +100 AND SQLERRD(3) = 0
DISPLAY 'NO ENCUENTRO NADA'
PERFORM 90000-FINAL
WHEN OTHER
DISPLAY 'ALGO VA MAL. EL SQLCODE ES: 'SQLCODE
PERFORM 90000-FINAL
END-EVALUATE
La variable de SQL SQLERRD(3) nos informa de cuantos registros se han recuperado en el FETCH (pudiese darse el caso de que nosotros quisiésemos recuperar 30 registros pero en la tabla sólo hubiese 10, el resultado del FETCH sería un SQLCODE=100 pero SQLERRD(3) > 0).
En nuestro caso el número de registros recuperados sería 6.
PERFORM UNTIL IND-REGISTROS GREATER SQLERRD(3)
PERFORM GUARDAR-EN-SAL-DATOS
END-PERFORM
Al terminar, cerraremos el cursor:
EXEC SQL
CLOSE CUR_TABLA
END-EXEC
Controlamos el SQLCODE. Si es distinto de cero daremos un error.
IF SQLCODE NOT EQUAL ZEROES
DISPLAY 'ERROR CERRANDO CURSOR. EL SQLCODE ES: 'SQLCODE
END-IF
Según la tabla de nuestro ejemplo, habríamos guardado en SAL-DATOS todos los registros.
Para finalizar devolvemos el control al programa llamante.
FINAL
GOBACK.
La sentencia ROWSET de DB2 se puede usar con otras instrucciones SQL. Se puede usar con el INSERT / UPDATE / DELETE.
Partimos de una rutina que realiza un CURSOR a una tabla para recuperar todos los registros que cumplan una determinada condición.
Nuestra rutina devolverá la información recuperada al programa llamante a través de una tabla de 10 ocurrencias definida en la linkage.
Vamos con el ejemplo:
Imaginemos que la tabla a la que queremos acceder tiene estos datos:
Siendo CAMPO1 la clave.
En esta versión del uso de cursores mostraremos el uso de la sentencia ROWSET para recuperar los datos.
Trabajaremos con un cursor ROWSET POSITIONING. Este
tipo de cursor nos permite recuperar uno o más registros en un solo FETCH.
Definimos un cursor del siguiente modo:
WORKING-STORAGE SECTION.
EXEC SQL
DECLARE CURSOR CUR_TABLA ROWSET POSITIONING FOR
SELECT CAMPO1,
CAMPO2,
CAMPO3,
CAMPO4,
CAMPO5
FROM TABLA1
WHERE CAMPO1 = :CLAVE-CAMPO1
ORDER BY CAMPO1
END-EXEC
01 TBL-FETCH.
05 TBL-CAMPO1 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO2 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO3 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO4 PIC XX OCCURS 100 TIMES.
05 TBL-CAMPO5 PIC XX OCCURS 100 TIMES.
01 HNUM-REGS PIC S9(9) COMP.
IMPORTANTE: La variable HNUM-REGS sera la variable HOST que indicará al FETCH cuantos registros queremos recuperar.
Esta variable tiene que ser binaria (tipo COMP) y además debe estar definida en el nivel de working 01.
En la linkage recibiremos la información de los campos clave.
LINKAGE SECTION.
01 ENTRADA.
05 NUM-REGISTROS PIC 9(4).
05 ENT-CAMPO1 PIC XX.
01 SALIDA.
05 SAL-DATOS OCCURS 10 TIMES.
10 SAL-CAMPO1 PIC XX.
10 SAL-CAMPO2 PIC XX.
10 SAL-CAMPO3 PIC XX.
10 SAL-CAMPO4 PIC XX.
10 SAL-CAMPO5 PIC XX.
En el inicio del programa informamos las variables de acceso al WHERE y realizaremos el OPEN del cursor:
INICIO
IF ENT-CAMPO1 EQUAL SPACES OR LOW-VALUES
DISPLAY 'LA CLAVE ESTA VACIA'
PERFORM 90000-FINAL
END-IF
MOVE ENT-CAMPO1 TO CLAVE-CAMPO1
Si no informa la variable número de registros la informamos con el número máximo de ocurrencias, en este caso 10.
IF NUM-REGISTROS EQUAL ZEROS OR LOW-VALUES
MOVE 10 TO HNUM-REGS
ELSE
MOVE NUM-REGISTROS TO HNUM-REGS
END-IF
EXEC SQL
OPEN CUR_TABLA
END-EXEC
Controlaremos el SQLCODE. Si no fuese cero, tendríamos que dar un error.
IF SQLCODE NOT EQUAL ZEROES
DISPLAY 'ERROR EN EL OPEN CURSOR. EL SQLCODE ES: 'SQLCODE
PERFORM 90000-FINAL
END-IF
En el proceso realizamos un FECTH para recuperar todos los registros marcados por la variable de entrada NUM-REGISTROS(HNUM-REGS) en una tabla interna(TBL-FETCH).
A continuación volcamos la información de nuestra tabla interna en la tabla de salida:
PROCESO
EXEC SQL
FETCH NEXT ROWSET CUR_TABLA FOR :HNUM-REGS ROWS
INTO :TBL-CAMPO1,
:TBL-CAMPO2,
:TBL-CAMPO3,
:TBL-CAMPO4,
:TBL-CAMPO5
END-EXEC
Controlamos el SQLCODE devuelto:
EVALUATE TRUE
WHEN SQLCODE EQUAL ZEROES
DISPLAY 'TODO EN ORDEN'
WHEN SQLCODE EQUAL +100 AND SQLERRD(3) > 0
DISPLAY 'TODO EN ORDEN'
WHEN SQLCODE EQUAL +100 AND SQLERRD(3) = 0
DISPLAY 'NO ENCUENTRO NADA'
PERFORM 90000-FINAL
WHEN OTHER
DISPLAY 'ALGO VA MAL. EL SQLCODE ES: 'SQLCODE
PERFORM 90000-FINAL
END-EVALUATE
La variable de SQL SQLERRD(3) nos informa de cuantos registros se han recuperado en el FETCH (pudiese darse el caso de que nosotros quisiésemos recuperar 30 registros pero en la tabla sólo hubiese 10, el resultado del FETCH sería un SQLCODE=100 pero SQLERRD(3) > 0).
En nuestro caso el número de registros recuperados sería 6.
PERFORM UNTIL IND-REGISTROS GREATER SQLERRD(3)
PERFORM GUARDAR-EN-SAL-DATOS
END-PERFORM
Al terminar, cerraremos el cursor:
EXEC SQL
CLOSE CUR_TABLA
END-EXEC
Controlamos el SQLCODE. Si es distinto de cero daremos un error.
IF SQLCODE NOT EQUAL ZEROES
DISPLAY 'ERROR CERRANDO CURSOR. EL SQLCODE ES: 'SQLCODE
END-IF
Según la tabla de nuestro ejemplo, habríamos guardado en SAL-DATOS todos los registros.
Para finalizar devolvemos el control al programa llamante.
FINAL
GOBACK.
La sentencia ROWSET de DB2 se puede usar con otras instrucciones SQL. Se puede usar con el INSERT / UPDATE / DELETE.
No hay comentarios.:
Publicar un comentario