Bienvenidos a Iseries Venezuela

Las mejores prácticas, recursos, tips, enlaces, videos y artículos para informáticos relacionados con el Iseries y el As/400 lenguajes de programación RPG, ILE RPG y SQL.

The best practices, resources, tips, links, videoes and articles for computer related to the Iseries and the As/400 languages of programming RPG, ILE RPG and SQL.

Monday, December 2, 2013

El Perro que se Muerde la Cola

















Cuando un registro del un archivo  queda “bloqueado” por el mismo job  que está ejecutando la aplicación, se genera un mensaje de error que es incomodo para la mayoría de los programadores.

El trabajo “bloquea el acceso” a un registro y luego intenta accederlo en alguna operación de Update mas adelante;  el tiempo de espera se agota y se produce el desconcertante mensaje:
“El registro ya está asignado en este trabajo”.

¿Cómo hice para que mi programa bloqueara el acceso a un registro que él mismo está procesando?.

Un caso en el que se produce este incomodo error es el siguiente.
Supongamos que hacemos una declaración de este tipo en la hoja F

FDirpfl001 uf a e           k disk

Tenemos un archivo de tipo UPDATE que además permite adicionar registros.
Generalmente llenamos el Subarchivo con un lazo que recorre el archivo declarado en la hoja F y lo va “vaciando” en cada registro del subarchivo en pantalla:

  setll *loval dirpfl001;   // se posiciona al principio del archivo
   Read Dirpfl001;         //  lee el primer registro
   Dow not %eof(dirpfl001); 
      Dsp_Cedo = Aescod;       // Llena los campos
      Dsp_Des = Aesdes;         //de pantalla
      Rrn = Rrn + 1;                 //graba en
      write fmtsfl;                  // el subfile
   Read Dirpfl001;           //lee el siguiente registro.
  enddo;                   


La declaración del archivo como UPDATE, tiene el efecto de que cada lectura que se hace sobre el archivo “retiene” el registro hasta que se produzca la lectura de otro registro o se realice un UDPATE sobre el mismo.  El último registro que se ha leído para llenar el subarchivo ha quedado “bloqueado” puesto que no le sigue la lectura de otro registro ni se ha realizado una operación update sobre este último registro.

El usuario puede seleccionar este registro para hacer update, luego de realizar los cambios pertinentes en pantalla. El programa trata de realizar una operación CHAIN sobre este registro y se produce el pavoroso error que deja al programador desconcertado.

El último registro leído no es el único caso de riesgo para la aparición de este error. Cualquier lectura de consulta que se realice sobre un registro mostrado en la pantalla implica generalmente un CHAIN al registro; se muestra el detalle de la data y luego el usuario decide o no modificar la información.  Si el usuario se queda en el nivel de consulta, todo marcha bien, pero si el usuario decide modificarlo luego de haberlo consultado. EL registro ya fue retenido con un read previo al hacer la consulta e inevitablemente al querer accederlo nuevamente para hacer un UPDATE,  se produce el error de acceso al registro, haciendo que el programa falle por tiempo de espera agotado.

¿Cómo resolver este problema?

Al realizar una consulta sobre un registro o al llenar el subfile de la pantalla, debe realizarse la lectura del archivo adicionando un (N) para impedir que el registro sea retenido en cada lectura (read.) Este bloqueo automático sucede por haber declarado el archivo de UPDATE aún cuando solo estemos leyendo el archivo. Entonces para impedir que el bloqueo automático sea activado en cada lectura, se indica una (N) al lado del Read o chain que evitará este inconveniente. Reescribiendo la rutina de llenado del subfile quedaría lo siguiente:

   setll *loval dirpfl001;   // se posiciona al principio del archivo
   Read(n)  Dirpfl001;         //  lee el primer registro
  Dow not %eof(dirpfl001); 
     Dsp_Cedo = Aescod;       // Llena los campos
     Dsp_Des = Aesdes;         //de pantalla
     Rrn = Rrn + 1;                 //graba en
     write fmtsfl;                  // el subfile
   Read(n) Dirpfl001;           //lee el siguiente registro.
  enddo;                   

Cuando va a realizarse efectivamente la actualización del registro con la combinación: Chain-update  o con la combinación read-update no debe colocarse la (N) en la lectura (read o chain) puesto que en ese punto si nos interesa que el registro esté bloqueado para que se realice el UPDATE correctamente.


Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo. 


Autor: Ing. Liliana Suárez



Monday, November 11, 2013

Comando SETOBJACC para reducir tiempos de procesamiento en el ISERIES




El comando SET Object Access  (SETOBJACC) puede cargar un archivo de base de datos, un índice de base de datos o un programa en un pool de memoria principal. La agrupación o pool  de almacenamiento puede ser una memoria privada, la memoria del trabajo que se está ejecutando, o una de las memorias comunes del sistema. El principal uso del comando es  proporcionar un mejor rendimiento de las aplicaciones para los trabajos que tienen acceso a un archivo de base de datos en un orden aleatorio o en una serie  de jobs que acceden al mismo archivo. Si la memoria es lo suficientemente grande para contener todos los datos, una vez que se carga el objeto, todos los accesos de lectura a los archivos se hacen sin una operación de lectura al disco, lo que elimina la mayor parte del tiempo de  procesamiento de acceso para ese archivo. Como resultado, se pueden realizar  mejoras dramáticas en tiempo de ejecución de trabajo. 

Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez

Wednesday, October 2, 2013

Conceptos de Trigger para Iseries y As/400




Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez 

Friday, August 30, 2013

Construir La clave de Lectura Desde una Estructura de Datos

 








Supongamos tenemos un archivo llamado: SISTEMAS que contiene
El inventario de Sistemas, Módulos y Programas del Departamento de Sistemas
Declaramos  una estructura de datos:

D CLAVEFILE DS  likerec(Sistemas:*key)
D SistemaID                  2A
D ModuloID                   2A
D ProgramaID              2A

Con la palabra clave LIKEREC establecemos que la DS va a ser una clave de acceso al archivo SISTEMAS
Una vez que los campos de la estructura de datos tienen los valores de acceso que necesitamos podemos realizar la siguiente operación:

En este ejemplo especificamos que usamos los tres primeros campos de la estructura de datos para armar la clave de lectura

  
Chain %KDS(CLAVEFILE:3)  sistemas;

También podemos hacer esto:
En este ejemplo especificamos que usamos los dos primeros campos de la estructura de datos para armar la clave de lectura

  SetLL %KDS(CLAVEFILE : 2 ) Sistemas;


¿y qué hago con esto?

Esta función es particularmente útil cuando recibimos por parámetro string de data de otras aplicaciones  y nos toca “desglosar”  en campos separados los datos recibidos para  luego armar claves totales y parciales necesarias para acceder a su vez a otros archivos o tablas.

Esto puede verse como una manera de restituir la declaración de  KLIST del RPG III. Para aquellos que puedan añorar la programación tradicional y no desean colocar en RPG FREE un chain con varias claves en el código del programa tal como esto:
Chain (clave1:clave2:clave3:clave4) pueden utilizar esta función
 Pueden utilizar el %KDS como otra alternativa de programación



Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez 


Friday, July 26, 2013

¿Para qué sirven las variables tipo apuntador (pointer)?




En cualquier lenguaje de programación, un apuntador es una variable cuyo contenido es la dirección en memoria de otra variable, una estructura de datos o un procedimiento.

En RPG IV (o Free) el tipo de variable APUNTADOR se especifica en la hoja D colocando este carácter en la posición correspondiente a la definición del tipo:   *
Esto le indica al compilador que la variable se utilizará para guardar la dirección en memoria de alguna otra estructura de datos. El contenido de esta variable tipo apuntador no se modifica a lo largo del programa. En cambio, para una variable de otro tipo (numérica, alfabética, estructura de datos, arreglos, etc.)  el programador puede modificar su valor.

Una variable tipo apuntador puede contener la dirección de un procedure o de una variable. Si el apuntador contiene la dirección de un procedure, debe utilizarse la palabra clave (Keyword) PROCPTR en la definición del apuntador.

Un apuntador que es utilizado para contener la dirección de variables o estructuras de datos es denominado “puntero de base” en inglés (basing pointer). Se puede acceder a variables, estructuras de datos y arreglos mediantes estos  punteros de base. La palabra clave (Keyword) BASED  es especificada en la definición de la variable cuyo valor es asignado según el contenido de una dirección de otra variable.

Un ejemplo de este código es el siguiente:
d  W_Pointer     s               *
d   w_nombre   s             30   inz(‘Maria Jimenez’)                  
d  Nombre         s             05    based(W_Pointer) 
W_pointer = %addr(W_nombre)

En este punto la variable Nombre tiene el contenido  ‘Maria’
Cabe destacar que mientras la variable W_pointer no tenga dirección asignada no se puede trabajar con la variable Nombre. Solo a partir del momento en que se asigna a la variable w_pointer una dirección de memoria con la operación %addr puede trabajarse con el contenido de la variable Nombre. Esto es así, porque la variables BASED no tienen memoria asignada hasta que el programa no esté cargado en memoria.
La variable Nombre hace referencia, en su definición a la variable tipo apuntador W_Pointer que va a contener la dirección en memoria de la variable que realmente contiene la data.

Muchos dirán: muy interesante el tema pero,  ¿Para qué sirve el uso de Apuntadores?

Las estructuras de datos y las variables que han sido declaradas BASED (la variable Nombre del ejemplo) pueden utilizar almacenamiento dinámico.

Con almacenamiento dinámico, la cantidad de memoria asignada al programa puede variar. Tradicionalmente cuando declaramos una matriz o arreglo (Array) con un numero incierto  de elementos. Declaramos el arreglo  con el máximo número de elementos que pensamos que pueden generarse a tiempo de ejecución, aun cuando raramente eso pueda suceder. Se desperdicia memoria y puede degradarse el rendimiento del equipo. Con el uso de apuntadores la historia cambia.

La función %Alloc asigna un numero de bytes en memoria a un apuntador.
En este ejemplo. Se declara un arreglo de 1000 posiciones. 
Sin embargo se asignan en memoria las primeras 100

d  W_Pointer     s               *
d   w_array        s             10     dim(1000) based(w_pointer)    
             
                 W_pointer = %Alloc(100)
                             W_pointer = %addr(W_array)


Memoria adicional puede ser asignada utilizando la función: %Realloc

                             w_pointer= %realloc(w_pointer:200)

Ahora se puede trabajar con 200 elementos del arreglo.

Parámetros tipo apuntador y apuntadores a procedures son muy utilizados en las Apis. Este uso y otros múltiples usos de los apuntadores los estaremos comentando en   próximos artículos.


Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez
 






Friday, June 28, 2013

Ejemplo SQLRPG y %LIKE para Búsqueda de Textos o Cadenas de Caracteres















Algunas veces puede resultar confuso manejar el %Like dentro del SQL embebido.
En esta oportunidad les entrego un código descargable como un ejemplo de como
manejar el like en un SQLRPGLE



Si colocas en BUSCAR un texto, desplegara en pantalla todos los municipios que tengan
ese string de caracteres en este caso: ANTONIO      

En este enlace puedes descargar el código fuente del programa y los archivos correspondientes
residentes en el archivo SQLLIKE.ZIP.

http://sdrv.ms/17WfsjI

Pd: Gracias a Frank Ronald por la sugerencia de publicar este tema.

Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez
 

Sunday, May 12, 2013

Aplicación para Listar Usuarios Activos del Iseries/AS400



 






En esta oportunidad les adjunto un programa que permite consultar los usuarios activos del Iseries, seleccionar uno de ellos y devolver su información en los parámetros de entrada. Cualquier programa que lo requiera puede invocar a esta aplicación en RPGLE y recoger en sus parámetros: usuario seleccionado y texto descriptivo de dicho usuario.

 Este programa es el resultado de la combinación  y ajuste de varios códigos publicados en páginas web para otros fines distintos al anteriormente descrito. Adapté estos códigos para producir un programa “nuevo”  que permitiera ver por pantalla los usuarios activos del Iseries. (Al final del artículo se listan los enlaces consultados)

Utilidad de este Programa:

Algunas veces para la instalación de software tales como menú dinámicos de seguridad o para establecer accesos a sistemas desarrollados y controlados por la Gerencia de Sistemas no se dispone de una ventana de consulta que permita seleccionar el usuario del Iseries sobre el cual se va a realizar la habilitación o restricción de acceso a determinadas opciones del aplicativo.
La aplicación que estoy adjuntando permite seleccionar un usuario activo del Iseries haciendo “doble Click” en la línea del subfile y en ese momento  el usuario seleccionado y su descripción se almacenan en los parámetros de entrada del programa y automáticamente se retorna al "programa llamador" los valores correspondientes. Al hacer Click con el Mouse en el botón SALIR, se termina la aplicación sin haber seleccionado ninguna usuario del Iseries.

Algunos analistas que se han visto en la necesidad de listar los usuarios activos del Iseries para programar ciertas restricciones de autoridad de acceso en sus aplicaciones, han tenido que recurrir al comando DSPUSRPRF con el parámetro  *ALL o *ENABLED (activos) o inactivos (*DISABLED) según sea el caso. Esto resulta engorroso al tener que dejar la salida de ese comando en un archivo temporal o de trabajo para luego procesar la información, cada vez que el usuario entre o salga de la aplicación.

Recursos internos de esta Utilidad:

El programa que estoy adjuntando utiliza User Spaces. Estos son espacios de memoria creados a tiempo de ejecución que son manejados con apuntadores y recorridos con el Offset calculado entre un elemento y la ubicación del otro. Digamos que son parecidos a los arreglos “arrays” con la diferencia de que los arreglos se acceden mediante índices; el User Space se maneja con apuntadores a las ubicaciones de memoria donde se almacena la data.
Los Users Spaces se utilizan, entre otras cosas,  para almacenar información delicada que no pueda ser manipulada por analistas autorizados aunque si puede ser consultada por estos para el desarrollo de aplicaciones. Una vez que el user space es utilizado en el programa y cargado en las variables de pantalla  se procede a eliminarlo. Aun cuando este User Space está siendo creado en la biblioteca Qtemp, si el usuario no ha abandonado la estación de trabajo puede crear problemas al entrar y salir de la aplicación constantemente por lo que puedes requerirse de la API DLTUSRSPC (DELETE USER SPACE). Los User Spaces son manejados por APIS. Estas son aplicaciones que residen en el sistema operativo del Iseries y son programadas para realizar funciones especiales que permitan al analista acceder a información o almacenarla sin que la integridad del sistema corra riesgos.

El programador puede adaptar esta utilidad para listar usuarios activos, inactivos o bajo cualquier otra condición. En esta versión se coloca específicamente “*ENABLED” en el código del programa para seleccionar usuarios Activos o Habilitados.

 Así queda a pantalla de esta aplicación:




En este enlace pueden descargar el código.




Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez
 


Webs Consultadas:

Wednesday, April 10, 2013

Ubicando el Cursor donde va.
















Un tip muy simple pero poderoso.  

En procesos interactivos, se realizan sucesivas validaciones de los valores ingresados por los usuarios en los campos de pantalla. Generalmente ocurre que el cursor no se posiciona en el campo que tiene el valor errado si no en el primer campo de entrada de datos. Aún cuando se colocan indicadores en el SDA con la palabra clave PC  condicionada para cada campo, el posicionamiento del cursor es errático en la práctica.Esta falta de control en la posición del cursor  resta agilidad al usuario en la carga de datos.

La palabra clave CSRLOC empleada en el archivo tipo SDA permite incluir variables que pueden ser manipuladas en el programa para forzar la posición del cursor en la fila y columna de la pantalla donde lo queremos colocar.
En el siguiente ejemplo vemos un archivo SDA a través de la utilidad SEU.

Colocamos la palabras clave CSRLOC indicándole los dos nombres de variables que van a ser empleadas en el programa para fijar la posición del cursor. En este caso colocamos la variable FILA para asociarla con la fila de posicionamiento del cursor y la variable COLU correspondiente a la columna. Por supuesto, el programador puede colocar los nombres que quiera…

Estas variables deben ser declaradas como campos ocultos en el SDA tal como se ve en el ejemplo.



En el Archivo SDA:

         A          R WIN00                                             
         A*
         A                                 WINDOW(3 3 14 18)       
         A                                  CSRLOC(FILA       COLU) 
         A                                  OVERLAY                 
         A            FILA               3S 0H
         A            COLU             3S 0H


En el programa RPG:

Podemos colocar:   

fila = 12
Colu = 56

Estas operaciones colocan el cursor en la fila 12 y columna 50 donde puede estar el campo validado con error.

En los subfiles de carga masiva de datos también es aplicable esta opción en cuanto a las validaciones de carga para ubicarse en la línea y el campo del subfile donde interesa resaltar o corregir el error.

La aplicación de esta palabra clave también puede ampliarse cuando en la pantalla hay uso de botones y el cursor tercamente se coloca en el botón desplegado en pantalla. Podemos ubicar el cursor en una posición neutral que no genere accidentalmente procesos de actualización de datos o navegación innecesaria de pantallas.



  
Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez
             





Monday, March 25, 2013

Ruptura de Control en la Programación Estructurada











 
Los desarrolladores más ortodoxos se aferran vehementemente al uso estricto de Estructuras  de Control para asegurarse de que los desarrollos sean realizados cumpliendo las normas de la programación Estructurada. Estos desarrolladores vivieron una época muy ardua en la que mantener un programa al día y realizarle cambios continuos, en una programación carente de estructura era un verdadero tormento. Había programas que requerían más de 150 páginas de desarrollo. Las compilaciones podían llegar a las 350 páginas y el seguimiento del código fuente en cuanto a la lógica empleada era tan complicado como descifrar un mensaje de las tropas enemigas en plena guerra.
Hay gente que no pueden escuchar la palabra: GOTO porque enseguida sacan la estaca y la cruz para liberarse de tan horrendo maleficio.
En la época de la programación no estructurada, el uso del GOTO procuraba cubrir la ausencia de estructuras de control que hicieran posible generar operaciones cíclicas y repetitivas en la lógica del programa. Aparecieron, afortunadamente, las siguientes sentencias:

Dow: Do while  (ejecute mientras se cumpla la  condición)
Dou: repeat  (ejecute hasta que se cumpla la condición)
For: (con los valores de iteración desde … hasta ejecute)
El select los if anidados y el Case se convirtieron en grandes aliados del programador que le permitieron desarrollar códigos más entendibles para sus colegas y para ellos mismos a lo largo del tiempo.
Para pesar de algunos,  los siguientes códigos de operación han logrado “colarse” y romper el esquema rígido que tanto alivio ocasiona a muchos desarrolladores, provocando reacciones encontradas de amor-odio entre las viejas y nuevas tendencias de programación.

                    Iter, Leave, Leavesr, GOTO

 
La idea de este artículo no es provocar una discusión infinita entre los desarrolladores sino ilustrar el uso beneficioso que puede darse a sentencias que pueden verse como peligrosas pero que no lo son tanto. 




Friday, February 22, 2013

Algunos códigos fuentes simples y útiles en RPGLE-FREE



 

 
 
 
 
 
 
Algunos códigos fuentes simples y  útiles en RPGLE-FREE
Para ejecutar comandos:

En la hoja D, declaramos:

d clpstm          s            300
d@runsyscmd       pr                  extpgm('QCMDEXC')
d cmd                          200a   options(*varsize) const
d cmdlen                        15p 5 const


Monitoreamos la sentencia para que el programa no falle estrepitosamente en caso de que haya un error de ejecución del comando.

En este ejemplo estamos haciendo un chkobj de un objeto. Si el objeto no existe, el error que arroja el sistema operativo es CPF9801 con La sentencia monitor y la operación  on-error, enviamos el mensaje al usuario sin que el programa deje de estar operativo.

monitor;
        clpstm = 'chkobj obj(' + %trim(libreria) +
                 '/' +  %trim(archivo) +
                ') objtype(*file)';
                @runsyscmd(clpstm : %size(clpstm));
                on-error;
                  Dsp_error = 'Archivo solicitado no existe';
    endmon;


Simplificando la Validando de Fechas

En la hoja D:

d  Wrk_Fecha        s               D   datfmt(*eur)

En el Ejemplo trabajamos la fecha en formato *EUR (DD.MM.AAAA), por lo que a nivel de programación esperamos que el usuario haya colocado la fecha en  formato *Eur o que la fecha venga de un archivo generado con ese formato. Sin embargo, cabe destacar que este ejemplo es aplicable a cualquier formato con el que se desee trabajar.

Detectamos que la fecha es inválida pero no especificamos la razón (si es por el día, el mes o el año) cada programador puede refinar el código si así lo desea.

monitor;                               
  Wrk_fecha = %date(Fecha:*EUR);       
  on-error;                             
  dsp_error = 'Fecha  Inválida';
Endmon;

Friday, February 8, 2013

SQL Embebido - Sentencia USING y algo mas...


 
 
          SQL EMBEBIDO

          Sentencia USING


Cuando hacemos SQL dinámicos  requerimos construir dinámicamente la instrucción SELECT para extraer los registros que necesitamos de la base de datos. Muchas veces  las condiciones de selección son cambiantes  porque los valores de búsqueda son distintos dependiendo del proceso. En el programa, utilizamos variables  que contienen el valor de búsqueda de uno o varios campos dentro de las tablas de datos.  Las variables en el algoritmo de programación van teniendo valores  cambiantes y no es posible  colocar en Hard Code (código duro)  la sentencia SELECT del SQL. La sentencia “USING” permite solucionar este inconveniente.

 

Supongamos que tenemos que generar un reporte de inventario para varias filiales de una corporación. Tenemos en la base de datos una tabla de empresas filiales:

01= filia1  02= filial2  03 = filial3

En RPG FREE

1.-Declaramos las variables de trabajo para construir la sentencia dinámica

D Varsql1         s           1000a    Inz(*Blanks)

D V_Sql1          s           1000a

2.-Construimos la sentencia dinámica.

 (Como no sabemos la compañía que hay listar  colocamos = ?

exec sql set :V_SQL1 =       

  'select *    '||           

  'from INVENTARIO   '||         

  'Where CIA = ? '    ||  

  'order by CIA';        

3.-Ejecutamos el PREPARE

exec sql Prepare varsql1 From :v_sql1;

4.-Declaramos el Cursor.

exec  sql Declare c1 dynamic Scroll Cursor for varsql1

5.-Ejecutamos el OPEN del Cursor

 exec sql open c1 using :Var_CIA;

En este punto, se entiende que serán procesados aquellos registros de la base de datos

Cuyo valor en el campo compañía sea igual al valor del contenido de la variable: Var_CIA

 

6.- Ejecutamos el Fetch que sea requerido

exec sql fetch next from c1 into :Filler

 
                                          
 

Un caso menos obvio en su programación es el %LIKE% para armar la sentencia SQL. (Like = que contenga algo parecido a este texto)

Para utilizar el %LIKE%  es necesario primero construir el contenido de la variable que será aplicada en el USING en forma adecuada. Es decir en este caso la variable:  Var_Cía no debería contiene un valor numérico o alfabético sino que es el resultado de la concatenación de varios elementos que hacen posible para el SQL interpretar lo que se está pidiendo procesar.

Por ejemplo, supongamos que queremos buscar una dirección que tenga la palabra MADRID. En este caso requerimos el uso del LIKE de la siguiente manera:

Utilizamos una variable que llamaremos CIUDAD bien sea que el usuario la introduzca por pantalla o que la manipulemos en el programa.

CIUDAD = MADRID

Vamos a denominar a la variable colocada en la sentencia USING como: QRY_CIUDAD

Hacemos lo siguiente:

QRY_CIUDAD = ‘%’ + %trim(CIUDAD) + ‘%’

La sentencia SQl la podemos construir normalmente:

exec sql set :V_SQL1 =

                    'select ESTADO, CIUDAD, Descri '||

                    'from libsuarez/ciudades '||

                    'Where ciudad like  ? '    ||

                    'order by ciudad';

Cuando abrimos el cursor podemos colocar

exec sql open c1 using :QRY_CIUDAD;

 

 

Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo.


Autor: Ing. Liliana Suárez