¿ Quieres imprimir esta página ? Volver a la página principal de Recursos iSeries AS400 ¿ Necesitas ayuda ? En pruebas
System i5 iSeries AS400 Recursos. Compartiendo generamos conocimiento
Novedades en Recursos iSeries AS400
Noticias tecnológicas

Documentos
SQL en programas RPG

Este documento es una traducción al castellano del capitulo 6.3 del Redbook sg245402 realizada por Walter Nasich
SQL en programas RPG

En lugar de usar operaciones de acceso a archivos de base de datos, tales como READ, CHAIN, UPDATE, y DELETE, podemos incrustar sentencias SQL en nuestros programas RPG IV y usar estas para procesar registros en los archivos de base de datos del AS/400. SQL es un estandard para el acceso a base de datos, y es usado por los clientes en diferentes plataformas.
Algunas razones para el uso de SQL:
SQL es un lenguaje mas natural y su codigo es facil de mantener y leer.
SQL puede simplificar la lógica cuando múltiples registros son incluidos en una operación, tales como UPDATE o DELETE.
Las operaciones SQL se realizan por un optimizador de consultas, el cual es mejorado con cada nueva versión, y automáticamente toma las ventajas de las nuevas tencologias de base de datos.
La migración de aplicaciones desde o al AS/400 es facil si las aplicaciones estan escritas usando un lenguaje estandard como el SQL

El codigo fuente que contiene sentencias SQL incrustadas debe ser primero procesadas por un Proprocesador SQL. Este trabajo reemplaza las sentencias SQL con llamadas a los programas de función correspondientes. Este proprocesador es parte del producto licenciado DB2 Query Manager y SQL Development Kit for AS/400, el cual debe estar disponible durante el desarrollo de la aplicación. En tiempo de ejecución el soporte esta incluido dentro del sistema operativo.

Reglas para el incrustado de sentencias SQL
Use las siguientes reglas cuando escriba un programa RPG IV con sentencias SQL incrustadas:
Ingrese sus sentencias SQL sobre las especificaciones C.
Comience sus sentencias SQL usando el delimitador /EXEC SQL en las posiciones 7 hasta 15, con la “/” en la posición 7.
Puede comenzar ingresando sentencias SQL sobre la misma linea donde comienza el delimitador o sobre una nueva linea.
Use el delimitador de linea de continuación, un “+” (signo más) en posición 7, para continuar su sentencias en lineas subsecuentes.
Use el delimitador de final /END-EXEC en las posiciones 7 hasta 15, con la “/” barra en posición 7, para señalar el fin de sus sentencia SQL.

Un ejemplo de una sentencia SQL UPDATE incrustada:

C/Exec Sql
C+ Update Parts
C+ Set PartDes = :DspDes,
C+ PartQty = :DspQty,
C+ PartPrc = :DspPrc,
C+ PartDat = :DspDat
C+ Where PartNum = :DspNum C/End-Exec

El miembro fuente que contiene el programa RPG IV con las sentencias SQL incrustadas debe ser del tipo SQLRPGLE. Esto indica a la opción 14 o 15 del PDM ejecutar el mandato CTRSQLRPGI, el cual es requerido para llamar al Preprocesador SQL.

Proprocesador SQL
El preprocesador SQL crea un miembro de archivo fuente de salida. Por omisión, este es creado en un archivo fuente temporario llamado QSQLTEMP1 en la biblioteca QTEMP, el cual es automáticamente borrado por el sistema al final del trabajo. Puede especificar el archivo fuente de salida como un nombre de archivo permanente en el mandado del preprocesador. Un miembro con igual nombre que el programa es agregado al archivo fuente de salida.
Este miemobro contiene los siguientes items:
Llamadas al soporte de tiempo de ejecuciòn del SQL, el cual remplaza las sentencias SQL incrustadas.
Sentencias SQL analizadas y con las sintaxis chequeada

Por omisión, el precompilador llama al compilador del lenguaje usando, CRTBNDRPG o CRTRPGMOD segun la opción del PDM seleccionada.

Manejo de exepciones y errores
SQL no se comunica directamente con el usuario final, pero devuelve codigos de error al programa de aplicación cuando un error o 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 manejadores globales de error con una sentencia WHENEVER.

Area de cominicaciones SQL
El preprocesador SQL automáticamente incluye el SQLCA (SQL Communication Area) en las especificaciones D del programa RPG IV antes de las primeras 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

Los valores SQLCOD y SQLSTT son puestos por le administrador de base de datos después de que cada sentencia SQL se ejecuta. Un programa debe chequear los valores de SQLCOD or SQLSTT para determinar si la ultima sentencia SQL fue exitosa:

Si SQL encuentra un error mientras procesa la sentencia, SQLCOD tiene un valor negativo, y los primeros dos caracteres del SQLSTT no son "00", "01", or "02".
Si SQL encuentra una advertencia (warning) pero en una condición valida durante el procesamiento de sentecias SQL, el SQLCOD tiene un numero positivo y los dos primeros caracteres del SQLSTT son "01".
Si su sentencia SQL es procesada sin encontrar una condición de error o advertencia, el SQLCOD retorna 0 y SQLSTT es "0000".

La condicion comunmente usada "No record found" (registro no encontrado) devuelve los valores SQLCOD = +100 or SQLSTT = "02000".
El area de comunicaciones contiene muchos otros campos con información relacionada con la sentencia SQL ejecutada.

La sentencia WHENEVER (donde quiera que)
Como alternativa de chequear los valores de SQLCOD o SQLSTT, un programador puede usar la sentencia WHENEVER.
Esta sentencia indica al SQL chequear SQLSTT y SQLCOD, y continuar la precesamiento de su programa o bifurcar a otra area de su 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 por el programador 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:

C/Exec Sql
C+ WHENEVER Condition Action
C/End-Exec

Hay tres condiciones que puede 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'
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.

Usando un cursor
Al contrario de las operaciones nativas de base de datos, las cuales son orientadas a un registro y permiten procesar unicamente un registro a la vez, 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. O, con una sentencia UPDATE, puede actualizar todos los registros en un archivo si la condición WHERE no es usada. Para lograr igual resultado con operaciones nativas, necesita escribir un bucle y testear diferentes condiciones. Por lo tanto, usando sentencias SQL puede simplificar algunas veces la lógica del programa.
De acuerdo con este comportamiento, una sentencia SELECT pone todos los registros seleccionados en una tabla resultado. Usualmente, un programa transferira todos estos registros desde la tabla de resultado SQL a un subfile así el usuario final puede ver estos. Para acceder a una tabla resultado, SQL provee una tecnica llamada cursor. Este es usado dentro de un programa SQL para mantener una posición en la tabla resultado.SQL usa un cursor para 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 relacionadas al uso de cursores:
DECLARE CURSOR, esta sentencia 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 renglon puede ser recuperados.
FETCH, recupera renglones desde la tabla resultado o posiciona el cursor sobre otro renglon.
CLOSE, cierra el cursor.

Los siguientes recortes de código muestran el uso de un cursor:
... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+..
C/Exec Sql
C+ DECLARE Cursor1 CURSOR FOR
C+ SELECT * FROM Pedidos
C+ ORDER BY Nroped
C+ FOR FETCH ONLY
C/End-Exec
C/Exec Sql
C+ OPEN Cursor1
C/End-Exec
C/Exec Sql
C+ FETCH Cursor1 INTO :SF1DS
C/End-Exec
C/Exec Sql
C+ CLOSE Cursor1
C/End-Exec

SQL soporta dos tipos de cursores: serial y scrollable. El tipo de cursor determina los metodos de posicionamiento que pueden ser usados con el cursor.

Cursor serial
Un cursor serial es definido por defecto, si la palabra clave SCROLL no es usada. Con un cursor serial, cada renglon 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 renglon en la tabla resultado. Con cada sentencia FETCH, el cursor es movido al siguiente renglon en la tabla resultado, el cual se vuelve el renglon actual. Si se especifican variables de programa (con la clausula INTO en la sentencia FETCH), SQL mueve el contenido del renglon actual a su variable de programa.
Esta secuencia es repetida cada vez que emite la sentencia FETCH, hasta el end-of-file (fin de archivo - SQLCOD = 100) es alcanzado. Cuando alcanza el end-of-file, cierre el cursor. Ya no puede acceder a ningun renglon de la tabla resultado despues de alcanzar el end-of-file. Para usar otra vez el cursor, debe primero cerrarlo y entonces volver a emitir la sentencia OPEN.

Cursor desplazable
Con un cursor desplazable (scrollable), los renglones 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. Este renglon se vuelve el renglon actual.
Las siguientes opciones de desplazamiento, relativas a la posición actual del cursor, se usadan 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.

Un programa con SQL incrustado de ejemplo

     H  DATEDIT(*DMY/)
      *----------------------------------------------------------------*
      * Utilización de Trefilas                                        *
      *----------------------------------------------------------------*
      * Indicadores                                                    *
      *----------------------------------------------------------------*
     FSP0004    IF   E           K DISK
     FSP0005    IF   E           K DISK
     FSPTCTR    IF   E             DISK
     FSP0208P1  O    E             PRINTER OFLIND(*IN75)
     FSP0208FM  CF   E             WORKSTN
     F                                     SFILE(SF1:SF1NBR)
     F                                     INFDS(CUR)
     D CUR             DS
     D  CURSOR               370    371B 0
      * De trabajo
     D FEISO           S               D
     D x               S              4  0
     D dias            S              4  0
      * Registro del Cursor WSP47
     D RWSP47          DS
     D  W47TRE                        6P 0
     D  W47MEI                        7P 2
     D  W47MES                        7P 2
     D  W47CAQ                        8A
     D  W47KIL                       11P 2
      *
     C     K005          KLIST
     C                   KFLD                    SELSEC
     C                   KFLD                    SELCEN
      *
     C                   MOVE      UDATE         FEISO
     C                   EXTRCT    FEISO:*D      dias
     C                   SUB       1             dias
     C                   SUBDUR    dias:*D       FEISO
     C     *DMY          MOVE      FEISO         SELFED
     C                   MOVE      UDATE         SELFEH
     C     1             CHAIN     RGTCTR                             01
     C  N01              MOVEL     SPCEMP        CTNO01
      *
      *----------------------------------------------------------------*
      * Pantalla 1 - Visualizacion                                     *
      *----------------------------------------------------------------*
      *
     C     P1            TAG
     C                   EXSR      VALI01
     C                   MOVEA     *IN(30)       IND30            10
     C     IND30         IFEQ      *ZEROS
     C                   EXSR      SF1FIL
     C                   ENDIF
      *
     C     P11           TAG
     C                   WRITE     F1
     C                   EXFMT     SFC1
      * F3=Fin
     C     *IN03         CABEQ     '1'           FIN
     C                   MOVEA     '0000000000'  *IN(30)
      * F4=Nómina
     C     *IN04         IFEQ      '1'
     C                   EXSR      AYUDA1
     C                   GOTO      P1
     C                   ENDIF
      * Cambios
     C     *IN26         CABEQ     '1'           P1
      * F10=Imprimir
     C     *IN10         IFEQ      '1'
     C     *IN51         ANDEQ     '1'
     C                   EXSR      IMPRIM
     C                   GOTO      P11
     C                   ENDIF
     C                   GOTO      P11
      *
     C     FIN           TAG
     C                   SETON                                        LR
      *----------------------------------------------------------------*
      * SF1FIL - Llena sf1 con renglones de estadística                *
      *----------------------------------------------------------------*
      *
     C     SF1FIL        BEGSR
     C                   SETON                                        50
     C                   WRITE     SFC1
     C                   SETOFF                                       5051
     C                   CLEAR                   SF1NBR
     C                   CLEAR                   TOTA01
      * Definición y apertura de Cursor
     C/Exec Sql
     C+ Declare WSP47 Cursor for
     C+   SELECT
     C+         A.TRE121, A.MEI121, A.MES121, C.F01CAQ, SUM(A.KIL121)
     C+         FROM "SP0121" A,
     C+              "SP0110" B,
     C+              "SP0001" C
     C+         WHERE (NOT(TRE121 = 0 AND MEI121 = 0 AND MES121 = 0)
     C+              AND (FEC121 >= :PFED)
     C+              AND (FEC121 <= :PFEH)
     C+              AND (:SELTRE = 0 OR TRE121 = :SELTRE)
     C+              AND (:SELSEC = 0 OR SEC121 = :SELSEC)
     C+              AND (:SELCEN = 0 OR CEN121 = :SELCEN))
     C+              AND (ORD121 = ORD110)
     C+              AND (ITE121 = ITE110)
     C+              AND (ART110 = F01COD)
     C+         GROUP BY A.TRE121, A.MEI121, A.MES121, C.F01CAQ
     C+         ORDER BY A.TRE121, A.MEI121, A.MES121, C.F01CAQ
     C+         For Fetch Only
     C/End-Exec
     C/Exec Sql
     C+         Open WSP47
     C/End-Exec
     C                   DO        999999
      * Obtiene un registro desde el cursor
     C/Exec Sql
     C+         Fetch WSP47 Into :RWSP47
     C/End-Exec
     C     SQLSTT        IFEQ      '02000'
     C                   LEAVE
     C                   ENDIF
      *
     C                   Z-ADD     W47KIL        KILSF1
     C                   ADD       W47KIL        TOTA01
      *
     C                   ADD       1             SF1NBR            4 0
     C                   WRITE     SF1
     C                   SETON                                        51
     C                   ENDDO
      *
      * Cierre del cursor
     C/Exec Sql
     C+         Close WSP47
     C/End-Exec
      *
     C                   ENDSR
      *----------------------------------------------------------------*
      * VALI01 - Valida selecciones                                    *
      *----------------------------------------------------------------*
      *
     C     VALI01        BEGSR
      * Fecha desde
     C     *DMY          TEST(D)                 SELFED                 30
     C  N30*DMY          MOVE      SELFED        FEISO
     C  N30*ISO          MOVE      FEISO         PFED              8 0
      * Fecha hasta
     C         *DMY        TEST(D)                 SELFEH                 31
     C  N31*DMY        MOVE      SELFEH        FEISO
     C  N31*ISO          MOVE      FEISO         PFEH              8 0
      *
     C                   CLEAR                   DESMAQ
      * Sección
     C     SELSEC        IFNE      *ZEROS
     C     SELSEC        CHAIN     RG004                              32
     C  N32              MOVEL     F04DES        DESMAQ
     C                   ENDIF
      * Centro
     C     SELSEC        IFNE      *ZEROS
     C     SELCEN        ANDNE     *ZEROS
     C     K005          CHAIN     RG005                              33
     C  N33              EVAL      DESMAQ = %trim(DESMAQ) + '/' + F05DES
     C                   ENDIF
     C                   ENDSR
      *----------------------------------------------------------------*
      * AYUDA1 - Ayuda pantalla 1                                      *
      *----------------------------------------------------------------*
      *
     C     AYUDA1        BEGSR
     C     CURSOR        DIV       256           FILA              3 0
     C                   MVR                     COLU              3 0
     C     FILA          IFEQ      3
      * Sección
     C     COLU          IFGE      10
     C     COLU          ANDLE     12
     C                   CALL      'SP3004'
     C                   PARM                    PSEC3             3 0
     C                   Z-ADD     PSEC3         SELSEC
     C                   ENDIF
      * Centro
     C     COLU          IFGE      14
     C     COLU          ANDLE     16
     C                   CALL      'SP3005'
     C                   PARM                    PSEC3
     C                   PARM                    PCEN3             3 0
     C                   Z-ADD     PSEC3         SELSEC
     C                   Z-ADD     PCEN3         SELCEN
     C                   ENDIF
     C                   ENDIF
     C                   ENDSR
      *----------------------------------------------------------------*
      * IMPRIM - Imprime                                               *
      *----------------------------------------------------------------*
      *
     C     IMPRIM        BEGSR
     C                   SETON                                        75
     C                   DO        9999          x
     C     x             CHAIN     SF1                                01
     C   01              LEAVE
      *
     C   75              WRITE     HEAD
     C                   SETOFF                                       75
     C                   WRITE     DETAL
     C                   ENDDO
     C                   WRITE     FINLIS
     C                   ENDSR

Puedes ver el código en formato texto aquí

Documento cedido por Walter Nasich

17-01-2002

Comentarios de usuarios

Nombre:
Mail:
Comentario:
 


 

NUESTRA COMUNIDAD EN
ÚNETE Y.... ¡¡ PARTICIPA !!
Dossiers técnicos iSeries y AS400
- Seguridad
- Alta disponibilidad.
Nuestros links favoritos
- Tendencias tecnologías de la información
Expertos en tecnologías de la información, nos dan su punto de vista sobre las tendencias actuales y futuras
- Los últimos anuncios sobre hardware-software para iSeries AS400 realizados por IBM
- Freeware y shareware para el iSeries AS400
- Utilidades para el iSeries AS400 realizadas por profesionales
- Documentos. Trucos e ideas para resolver tus problemas
- Los manuales y links más interesantes del iSeries AS400

  Links patrocinados
  •  
  •  

[ Soy nuevo |   Profesionales |   AS qué |   Empresas |    Foros |   Recomiéndanos |    Productos ]
 
Recursos iSeries AS400. Es una web de: PUBLICACIONES HELP400, S.L. CIF:B-60-202827 Gran Vía de les Corts Catalanes, núm. 715, Entresuelo – 3ª - Barcelona - Tel.+34.932.310.049