SQL EN PROGRAMAS RPG
RPG permite el uso de operaciones SQL en lugar de uitlizar operaciones de base de datos, como READ, CHAIN, UPDATE, y DELETE.
¿Porqué utilizar operaciones SQL?
SQL es un lenguaje natural, facil de mantener y leer. SQL
puede simplificar la lógica cuando múltiples registros son incluidos en una operación, como UPDATE o DELETE. Las operaciones son ejecutadas por medio de un
optimizador de consultas. La
migración de aplicaciones desde o al IBM i (AS/400) es facil si las aplicaciones estan
escritas usando un lenguaje estandard como el SQL.Las sentencias SQL son procesadas por el Proprocesador
SQL.

Reglas para la codificación en RPG.
Las sentencias SQL se deben ingresar sobre las
especificaciones C o en la sección de codificación. Deben comienzar SQL con el delimitador /EXEC SQL. La sentencias SQL se pueden ingrear sobre la misma linea donde comienza el delimitador o
sobre una nueva linea. Se debe utilizar el delimitador de linea de continuación, un “+”
(signo más) para continuar la codificación de sentencias en lineas subsecuentes. El delimitador de final /END-EXEC señala el fin de sus sentencia SQL.Los fuentes de los programas RPG que contienen SQL deben ser del tipo SQLRPGLE.Para crear los programas SQL RPG se debe utilizar el comando CTRSQLRPGI, el cual es requerido para llamar al Preprocesador SQL.Nota: en la versión FREE-Form de RPG no se requiere el slash "/" ni el simbolo "+".
Ejemplo de una sentencia SQL
UPDATE incrustada:
/Exec Sql
+ Update Parts
+ Set PartDes = :DspDes,
+ PartQty = :DspQty,
+ PartPrc = :DspPrc,
+ PartDat = :DspDat
+ Where PartNum = :DspNum
/End-Exec
Manejo de exepciones y errores.
SQL devuelve codigos de
error al programa de aplicación cuando una excepción ocurre. Estos
codigos de error pueden ser usados de dos maneras: Chequeando codigos de error
en un area de comunicaciones SQL. Definiendo gestores globales de error con
una sentencia WHENEVER.
Area de comunicaciones SQL.
El preprocesador SQL
automáticamente incluye el SQLCA (SQL Communication Area) en las
especificaciones D del programa RPG antes de las especificaciones
C. Por lo tanto, no es necesario codificar INCLUDE SQLCA en el programa fuente.
El
SQLCA, incluido en el programa ILE RPG, contiene los siguientes campos:
D* SQL Communications area
D SQLCA DS
D SQLAID 1 8A INZ(X'0000000000000000')
D SQLABC 9 12B 0
D SQLCOD 13 16B 0
D SQLERL 17 18B 0
D SQLERM 19 88A
D SQLERP 89 96A
D SQLERRD 97 120B 0 DIM(6)
D SQLERR 97 120A
D SQLER1 97 100B 0
D SQLER2 101 104B 0
D SQLER3 105 108B 0
D SQLER4 109 112B 0
D SQLER5 113 116B 0
D SQLER6 117 120B 0
D SQLWRN 121 131A
D SQLWN0 121 121A
D SQLWN1 122 122A
D SQLWN2 123 123A
D SQLWN3 124 124A
D SQLWN4 125 125A
D SQLWN5 126 126A
D SQLWN6 127 127A
D SQLWN7 128 128A
D SQLWN8 129 129A
D SQLWN9 130 130A
D SQLWNA 131 131A
D SQLSTT 132 136A
D* End
of SQLCA
Para determinar si una senteicna SQL fue exitosa, el sistema operativo devuelve los valores de respuesta en las variables SQLCOD y SQLSTT. Los programas RPG deben chequear los valores de estas variables y validar:
- Si SQL encuentra un error
mientras procesa la sentencia, la variable SQLCOD contendrá un valor negativo, y los primeros
dos caracteres de la variable SQLSTT serán diferentes de "00", "01", o "02".
- Si SQL encuentra una advertencia (warning) pero en una
condición válida durante el procesamiento de sentecias SQL, el SQLCOD tendrá un
numero positivo y los dos primeros caracteres del SQLSTT serán "01".
- Si
su sentencia SQL es procesada sin encontrar una condición de error o
advertencia, el SQLCOD retornará 0 y SQLSTT será "0000".
- Si no se encuentra un registro, SQL devuelve los valores
SQLCOD = +100 o SQLSTT = "02000".
El area de comunicaciones contiene
muchos otros campos con información relacionada con la sentencia SQL ejecutada. Por ejemplo, la sentencia WHENEVER, es una alternativa en lugar de chequear los
valores de SQLCOD o SQLSTT. Esta
sentencia indica al SQL chequear SQLSTT y SQLCOD, y continuar la precesamiento o bifurcar a otra area del programa si un error, exepcion, o
advertencia existe como resultado de la ejecuciòn de una sentencia SQL. Un
manejador de condiciones de excepción puede ser escrito para
examinar los campos SQLCOD o SQLSTT para tomar una acción especifica para la
situación de error o excepción.
La sentencia WHENEVER tiene la
siguiente apariencia:
/Exec Sql
+ WHENEVER Condition Action
/End-Exec
Hay tres condiciones que se pueden especificar:
- SQLWARNIN: SQLCOD contiene un valor positivo diferente de 100
- SQLERROR: SQLCOD contiene un valor negativo (condición de error)
- NOT FOUND: SQLCOD = +100 o SQLSTT = '02000'
Se puede especifiar la acción que quiere para cada condición
- CONTINUE: El programa continua con la siguiente sentencia
- GO TO etiqueta: El programa bifurca a la etiqueta (TAG) dentro del programa.
Cursores SQL
Las sentencias
SQL son orientadas a multiples registros y pueden manejar un grupo de registros
a la vez. Por ejemplo, con una sentencia DELETE puede borrar todos los
artículos de un pedido. Para lograr el procesamiento de los datos devuelltos por SQL registro a registro, se necesita escribir un bucle y validar diferentes condiciones.
De acuerdo con este comportamiento,
una sentencia SELECT pone todos los registros seleccionados en una tabla
resultado. Un programa transferira todos estos registros desde la
tabla de resultado SQL a un subfile. Para
acceder a una tabla resultado, SQL provee una tecnica llamada cursor. Este es
ustilizado para mantener una posición en la tabla
resultado, permitiendo trabajar con los renglones en la tabla
resultado y hacer que esten disponibles para el programa. Un programa puede tener
varios cursores, aunque cada uno debe tener un único nombre.
Sentencias para el uso de
cursores:
- DECLARE CURSOR: define el nombre del cursor y
especifica los renglones a ser recuperados con una sentencia SQL incrustada.
- OPEN: abre el cursor para su uso dentro del programa. El cursor debe estar abierto
antes de que cualquier registro puede ser recuperados.
- FETCH: recupera registros desde la tabla resultado o posiciona el cursor sobre otro registro.
- CLOSE: cierra el cursor.
Los siguientes recortes de código
muestran el uso de un cursor:
/Exec Sql
+ DECLARE Cursor1 CURSOR FOR
+ SELECT * FROM Pedidos
+ ORDER BY Nroped
+ FOR FETCH ONLY
/End-Exec
/Exec Sql
+ OPEN Cursor1
/End-Exec
/Exec Sql
+ FETCH Cursor1 INTO :SF1DS
/End-Exec
/Exec Sql
+ CLOSE Cursor1
/End-Exec
SQL soporta dos tipos de cursores:
serial y scrollable, que determina los metodos de posicionamiento
que pueden ser usados.
- Cursor serial: es
definido por defecto, si la palabra clave SCROLL no es usada. Con un cursor
serial, cada registro de la tabla resultado puede ser tomado unicamente una vez
por cada OPEN del cursor. Cuando un cursor es abierto, este es posicionado
antes del primer registro. Con cada sentencia FETCH, el
cursor es movido al siguiente registro. Si se especifican variables de programa (con la clausula
INTO en la sentencia FETCH), SQL mueve el contenido del regiestro actual a la variable de programa. Esta secuencia es repetida cada vez que emite la sentencia FETCH, hasta que el
end-of-file (fin de archivo - SQLCOD = 100) es alcanzado, cerrando el cursor. Para usar otra vez el cursor, se debe primero cerrar y entonces volver a emitir la sentencia OPEN.
- Cursor desplazable: Con un cursor
desplazable, los registros de la tabla resultado pueden ser
tomados muchas veces. El cursor se mueve a travez de la tabla resultado en
función a la opción de posicion especificado en la sentencia FETCH. Cuando un
cursor es abierto, este se posiciona antes del primer renglon en la tabla
resultado. Con una sentencia FETCH, el cursor es posicionado sobre el renglon
en la tabla resultado que se especifique por la opciòn de posiciòn.
Las siguientes son opciones de
desplazamiento, que se usan para
posicionar el cursor cuando emite la sentencia FETCH:
- NEXT Posiciona el cursor sobre el siguiente renglon. (opcion por
omisión)
- PRIOR Posiciona el cursor sobre el renglon previo.
- FIRST Posiciona el cursor sobre el primer renglon.
- LAST Posiciona el cursor sobre el último renglon.
- BEFORE Posiciona el cursor antes del primer renglon.
- AFTER Posiciona el cursor despues del ultimo renglon.
- CURRENT No cambia la posición del cursor.
- RELATIVE n Posiciona el cursor en n renglones relativo a la posiciòn actual.