Db2 – Cursores en Procedimientos Almacenados

Tenemos el siguiente escenario:  Dada una tabla de países necesitamos convertir su contenido a una cadena de valores separados por coma.  Dado que una sentencia Select nos devuelve el contenido de la tabla podríamos hacer un procedimiento de conversión en alguno de nuestros programas para realizar lo solicitado o podríamos crear un procedimiento almacenado que haciendo uso de un cursor convierta las filas de una tabla en una cadena.   Si deseas conocer más acerca de los cursores en DB2 te recomiendo leer el siguiente enlace: Declare Cursor Statement

Importante** Dado que mi intención es hacer muy genérico el tema usaremos dummy como tabla de muestra.

Lo primero por hacer será definir la consulta responsable de proporcionarnos la lista de países. Esta consulta hará uso de dummy para listar 4 países como puede verse a continuación:

 SELECT Pais 
   FROM (
           SELECT 1 ID, 'México' Pais
             FROM sysibm.sysdummy1 union
           SELECT 2 ID, 'Brasil' Pais
             FROM sysibm.sysdummy1 union
           SELECT 3 ID, 'Panamá' Pais
             FROM sysibm.sysdummy1 union
           SELECT 4 ID, 'Venezuela' Pais
             FROM sysibm.sysdummy1
        ) TABLAPAISES;

Ahora vamos a declarar el procedimiento almacenado responsable de convertir las filas en una cadena. Para ello vamos a usar un parámetro de salida que almacenará la cadena resultante: 

CREATE PROCEDURE BaseDeDatos.SPFILASACADENA
            (
              INOUT PV_CADENA VARCHAR(500)   -- STRING DE PAISES
            )
          LANGUAGE SQL
          SPECIFIC SPFILASACADENA

BEGIN

END;

Dado el procedimiento y la consulta de países vamos a definir el cuerpo del procedimiento almacenado. Debido a que usaremos un cursor para recorrer las filas devueltas por la sentencia Select, será necesario hacer uso de la variable SQLCODE definida por DB2 para dar seguimiento a los estatus de diversas sentencias SQL.  Si deseas conocer más acerca de esto puedes leer el siguiente enlace:  Variables SQLSTATE y SQLCODE 

Como lo establece la documentación vamos a declarar nuestra variable SQLCODE al inicio del procedimiento, después declaramos la variable donde almacenaremos el valor de la fila obtenida en cada avance del cursor y después haremos la declaración del cursor:

    DECLARE SQLCODE  Integer       default 0;
    DECLARE VV_Pais  VARCHAR(100)  default '';
    DECLARE CurDetPaises CURSOR
           FOR     SELECT Pais 
                        FROM (
                                         SELECT 1 ID, 'México' Pais
                                             FROM sysibm.sysdummy1 union
                                         SELECT 2 ID, 'Brasil' Pais
                                             FROM sysibm.sysdummy1 union
                                         SELECT 3 ID, 'Panamá' Pais
                                            FROM sysibm.sysdummy1 union
                                         SELECT 4 ID, 'Venezuela' Pais
                                             FROM sysibm.sysdummy1
                                 ) TABLAPAISES;

y por último vamos a codificar el recorrido del cursor y el armado de la cadena con el contenido de cada fila devuelta por la sentencia Select:

  SET PV_CADENA = '';
  OPEN CurDetPaises;
  FETCH CurDetPaises INTO VV_Pais;
  WHILE SQLCODE <> 100 DO
     SET  PV_CADENA = PV_CADENA || ',' || VV_Pais;
     FETCH CurDetPaises INTO VV_Pais;
  END WHILE;
  CLOSE CurDetPaises;

Como puede verse el uso de SQLCODE es muy importante pues establece el punto de parada del cursor por lo que no debe olvidarse su declaración así como la declaración de las variables que almacenarán el valor de cada columna devuelta por la sentencia Select. 

Al ejecutar el procedimiento almacenado obtendremos lo siguiente:

CALL DMJFZ.SPFILASACADENA('')
Return Code = 0
Output Parameter #1 = ,México,Brasil,Panamá,Venezuela

y por último  este es el bloque completo del procedimiento almacenado:

CREATE PROCEDURE BASEDEDATOS.SPFILASACADENA
            (
              INOUT PV_CADENA VARCHAR(500)   -- STRING DE PAISES
            )
          LANGUAGE SQL
          SPECIFIC SPFILASACADENA
BEGIN

    DECLARE SQLCODE  Integer     default 0;
    DECLARE VV_Pais  VARCHAR(100)     default '';
    DECLARE CurDetPaises CURSOR
                            FOR SELECT Pais 
                           FROM (
                                 SELECT 1 ID, 'México' Pais
                                   FROM sysibm.sysdummy1 union
                                 SELECT 2 ID, 'Brasil' Pais
                                   FROM sysibm.sysdummy1 union
                                 SELECT 3 ID, 'Panamá' Pais
                                   FROM sysibm.sysdummy1 union
                                 SELECT 4 ID, 'Venezuela' Pais
                                   FROM sysibm.sysdummy1
                                 ) TABLAPAISES;

  SET PV_CADENA = '';
  OPEN CurDetPaises;
  FETCH CurDetPaises INTO VV_Pais;
  WHILE SQLCODE <> 100 DO
     SET  PV_CADENA = PV_CADENA || ',' || VV_Pais;
     FETCH CurDetPaises INTO VV_Pais;
  END WHILE;
  CLOSE CurDetPaises;

END;

Sé el primero en comentar

Deja un comentario