Cobol Foro

Cobol Foro (https://www.cobolforo.es/index.php)
-   Cocina PowerCOBOL (https://www.cobolforo.es/forumdisplay.php?f=24)
-   -   [PowerCOBOL] SQlite3 con PowerCobol (https://www.cobolforo.es/showthread.php?t=1642)

Josber 13 de mayo de 2023 14:06

Cita:

Citación del post de Joseg (Mensaje 8901)
Hola,

Como implementar un loop en PowerCobol?

Ejemplo de lista de todos los registros de "MyTable":
Código SQL:
  1. SELECT * FROM MyTable

Creo que tienes que usar "sqlite3_prepare" y "sqlite3_step", o implementar una "devolución de llamada" (callback),
Código COBOL:
  1. 01 CALLBACK USAGE PROCEDURE-POINTER.

... pero no lo estoy consiguiendo.

Gracias,
Jose

A ver, yo con SQLLite, no lo sé, porque no lo he usado nunca pero, con SQL_Embebido o SQL normal, lo que se hace para hacer un bucle es, lo primero, crear un cursor y lo segundo es un FETCH a ese cursor, hasta que SQLSTATE, sea "02000", que indica un "fin_de_fichero", por lo que me supongo que en este caso, será muy parecido, es que otra manera de hacerlo, me parece rara

En PWC, con SQL_Embebido, sería algo así:

Código COBOL:
  1. EXEC SQL
  2.         DECLARE  cursor_consulta CURSOR FOR
  3.                        SELECT * FROM CLIENTES
  4.                                    WHERE .....
  5.                                    ORDER BY .....
  6. END-EXEC.
  7.  
  8. INITIALIZE SQLSTATE.
  9.  
  10. EXEC SQL
  11.          OPEN cursor_consulta
  12. END-EXEC.
  13.  
  14. PERFORM WITH NO LIMIT
  15.                EXEC SQL
  16.                        FETCH cursor_consulta
  17.                                  INTO .....
  18.                END-EXEC
  19.                IF SQLSTATE = "02000"
  20.                    EXEC SQL
  21.                             CLOSE cursor_consulta
  22.                    END-EXEC
  23.                    EXIT PERFORM
  24.                END-IF
  25. END-PERFORM.

por lo menos, esa es la manera con la que yo hago un bucle. Lo puedes hacer con un PREPARE también pero, es más lioso, y se usa si tienes que montar la consulta armando un STRING, pero ese es otro tema.

Un salu2.-

Joseg 15 de mayo de 2023 17:08

Cita:

Citación del post de fastpho (Mensaje 8905)
@Joseg
La funcion sqlite3_step espera el valor por value no por reference seria asi :
Código COBOL:
  1. working-storage.
  2. 01 stmt-handle   PIC 9(9) COMP-5.
  3. 01 redefines stmt-handle.
  4.     05  pStmt usage pointer.


Código COBOL:
  1.      call "sqlite3_step"  & X"00" WITH  STDCALL  LINKAGE
  2.            using  by value stmt-handle
  3.            returning BD-STATUS
  4.      end-call
Saludos...


Ok, la función "sqlite3_step" ya está bien.
La función "sqlite3_column_count" también está bien.

La siguiente función siempre devuelve NULL (5)
Código COBOL:
  1.      move 1 to wnum-columns
  2.      call "sqlite3_column_type"  & X"00"  WITH  STDCALL  LINKAGE
  3.                            using
  4.                                    by value stmt-handle
  5.                                    by value wnum-columns
  6.                                    returning BD-COLUMNA-TIPO
  7.      end-call
¿Puede publicar una parte del código que se repite desde una tabla hasta que los datos se puedan consultar en PowerCobol?

Gracias por la ayuda.
Jose

fastpho 15 de mayo de 2023 20:28

Hola @Joseg como recorrer la tabla para saber que tipo valor se puede almacenar por columnas
Código COBOL:
  1. *-------------------------------------------------------------------------      
  2. *>STEP
  3. *-------------------------------------------------------------------------
  4.      DISPLAY "------------------".
  5.      DISPLAY "sqlite3_step      ".
  6.  
  7.      PERFORM DB-STEP.
  8.      evaluate bd-status
  9.      when  SQLITE_ROW  
  10.         perform muestro-cabecera
  11.      when  SQLITE_DONE
  12.         display "termino"
  13.         continue
  14.      when other
  15.         display "error"
  16.         exit program
  17.      end-evaluate.
  18. *-------------------------------------------------------------------------    
  19. *>FINALIZE
  20. *-------------------------------------------------------------------------
  21.      DISPLAY "------------------".
  22.      DISPLAY "sqlite3_finalize".
  23.  
  24.      MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB.
  25.      MOVE "sqlite3_finalize"      TO FUNCIONES-SQLITE3-LIB.    
  26.      
  27.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  28.               USING        BY VALUE   stmt-handle
  29.                            returning  BD-STATUS
  30.  
  31.      end-call.          
  32.    
  33.      IF BD-STATUS NOT = SQLITE_OK then
  34.           DISPLAY "ERROR "
  35.      
  36.      ELSE
  37.           DISPLAY "OK"
  38.      END-IF.
  39. *-------------------------------------------------------------------------    
  40. *>CLOSE_V2
  41. *-------------------------------------------------------------------------
  42.      DISPLAY "------------------".
  43.      DISPLAY "sqlite3_close_v2".
  44.  
  45.      MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB.
  46.      MOVE "sqlite3_close_v2"      TO FUNCIONES-SQLITE3-LIB.    
  47.      
  48.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  49.               USING        BY VALUE   BD-HANDLE
  50.                            returning  BD-STATUS
  51.  
  52.      end-call.          
  53.    
  54.      IF BD-STATUS NOT = SQLITE_OK then
  55.              CALL "BD-ERROR"
  56.           EXIT PROGRAM
  57.      ELSE
  58.           DISPLAY "OK"
  59.      END-IF.
  60.          
  61.      
  62.      EXIT PROGRAM.
  63.  
  64. *-------------------------------------------------------------------------
  65.  MUESTRO-CABECERA.
  66. *-------------------------------------------------------------------------
  67.  
  68.      PERFORM  DB-CANTIDAD-COLUMNAS.
  69.      
  70.      MOVE ZEROS TO BD-COLUMNA-NUMERO.
  71.      PERFORM VARYING BD-COLUMNA-NUMERO  FROM 0 BY 1  UNTIL BD-COLUMNA-NUMERO = BD-COLUMNA-CANTIDAD
  72.     *>sqlite3_column_type
  73. *          DISPLAY "--------------------"
  74. *          DISPLAY "sqlite3_column_type"
  75.  
  76.            MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB
  77.            MOVE "sqlite3_column_type"   TO FUNCIONES-SQLITE3-LIB    
  78.  
  79.            call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  80.              USING        BY VALUE   stmt-handle
  81.                           BY VALUE   BD-COLUMNA-NUMERO *> COMIENZA DE 0 LAS COLUMNAS HASTA sqlite3_column_count - 1
  82.                           returning  BD-COLUMNA-TIPO   *> RETORNA EL TIPO DE COLUMNA
  83.            end-call          
  84.  
  85.           DISPLAY "--------------------"
  86.           DISPLAY " COL NRO : " , BD-COLUMNA-NUMERO  , " es  COLUMNA-TIPO  " , BD-COLUMNA-TIPO  
  87.           DISPLAY "--------------------"
  88.      END-PERFORM.
  89.  
  90. *-------------------------------------------------------------------------
  91.  DB-CANTIDAD-COLUMNAS.
  92. *-------------------------------------------------------------------------
  93. *>sqlite3_column_count
  94. *    DISPLAY "--------------------".
  95. *    DISPLAY "sqlite3_column_count".
  96.  
  97.      MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB.
  98.      MOVE "sqlite3_column_count"  TO FUNCIONES-SQLITE3-LIB.    
  99.  
  100.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  101.               USING        BY VALUE   stmt-handle
  102.                            returning  BD-COLUMNA-CANTIDAD
  103.  
  104.      end-call.          
  105.  
  106. *     DISPLAY "BD-COLUMNA-CANTIDAD : " , BD-COLUMNA-CANTIDAD.
  107.  
  108. *-------------------------------------------------------------------------
  109.  DB-STEP.
  110. *-------------------------------------------------------------------------
  111. *>sqlite3_step
  112. *    DISPLAY "--------------------".
  113. *    DISPLAY "sqlite3_step".
  114.  
  115.      MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
  116.      MOVE "sqlite3_step"          TO FUNCIONES-SQLITE3-LIB.    
  117.  
  118.      call     FUNCIONES-SQLITE3-LIB  WITH STDCALL LINKAGE
  119.               USING        BY VALUE   stmt-handle
  120.                            returning  BD-STATUS
  121.  
  122.      end-call.      
  123. *    DISPLAY BD-STATUS.    
  124.      
  125.  
  126.  
Saludos ...

Joseg 16 de mayo de 2023 17:48

Cita:

Citación del post de fastpho (Mensaje 8910)
Hola @Joseg como recorrer la tabla para saber que tipo valor se puede almacenar por columnas
Código COBOL:
  1. *-------------------------------------------------------------------------      
  2. *>STEP
  3. *-------------------------------------------------------------------------
  4.      DISPLAY "------------------".
  5.      DISPLAY "sqlite3_step      ".
  6.  
  7.      PERFORM DB-STEP.
  8.      evaluate bd-status
  9.      when  SQLITE_ROW  
  10.         perform muestro-cabecera
  11.      when  SQLITE_DONE
  12.         display "termino"
  13.         continue
  14.      when other
  15.         display "error"
  16.         exit program
  17.      end-evaluate.
  18. *-------------------------------------------------------------------------    
  19. *>FINALIZE
  20. *-------------------------------------------------------------------------
  21.      DISPLAY "------------------".
  22.      DISPLAY "sqlite3_finalize".
  23.  
  24.      MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB.
  25.      MOVE "sqlite3_finalize"      TO FUNCIONES-SQLITE3-LIB.    
  26.      
  27.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  28.               USING        BY VALUE   stmt-handle
  29.                            returning  BD-STATUS
  30.  
  31.      end-call.          
  32.    
  33.      IF BD-STATUS NOT = SQLITE_OK then
  34.           DISPLAY "ERROR "
  35.      
  36.      ELSE
  37.           DISPLAY "OK"
  38.      END-IF.
  39. *-------------------------------------------------------------------------    
  40. *>CLOSE_V2
  41. *-------------------------------------------------------------------------
  42.      DISPLAY "------------------".
  43.      DISPLAY "sqlite3_close_v2".
  44.  
  45.      MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB.
  46.      MOVE "sqlite3_close_v2"      TO FUNCIONES-SQLITE3-LIB.    
  47.      
  48.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  49.               USING        BY VALUE   BD-HANDLE
  50.                            returning  BD-STATUS
  51.  
  52.      end-call.          
  53.    
  54.      IF BD-STATUS NOT = SQLITE_OK then
  55.              CALL "BD-ERROR"
  56.           EXIT PROGRAM
  57.      ELSE
  58.           DISPLAY "OK"
  59.      END-IF.
  60.          
  61.      
  62.      EXIT PROGRAM.
  63.  
  64. *-------------------------------------------------------------------------
  65.  MUESTRO-CABECERA.
  66. *-------------------------------------------------------------------------
  67.  
  68.      PERFORM  DB-CANTIDAD-COLUMNAS.
  69.      
  70.      MOVE ZEROS TO BD-COLUMNA-NUMERO.
  71.      PERFORM VARYING BD-COLUMNA-NUMERO  FROM 0 BY 1  UNTIL BD-COLUMNA-NUMERO = BD-COLUMNA-CANTIDAD
  72.     *>sqlite3_column_type
  73. *          DISPLAY "--------------------"
  74. *          DISPLAY "sqlite3_column_type"
  75.  
  76.            MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB
  77.            MOVE "sqlite3_column_type"   TO FUNCIONES-SQLITE3-LIB    
  78.  
  79.            call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  80.              USING        BY VALUE   stmt-handle
  81.                           BY VALUE   BD-COLUMNA-NUMERO *> COMIENZA DE 0 LAS COLUMNAS HASTA sqlite3_column_count - 1
  82.                           returning  BD-COLUMNA-TIPO   *> RETORNA EL TIPO DE COLUMNA
  83.            end-call          
  84.  
  85.           DISPLAY "--------------------"
  86.           DISPLAY " COL NRO : " , BD-COLUMNA-NUMERO  , " es  COLUMNA-TIPO  " , BD-COLUMNA-TIPO  
  87.           DISPLAY "--------------------"
  88.      END-PERFORM.
  89.  
  90. *-------------------------------------------------------------------------
  91.  DB-CANTIDAD-COLUMNAS.
  92. *-------------------------------------------------------------------------
  93. *>sqlite3_column_count
  94. *    DISPLAY "--------------------".
  95. *    DISPLAY "sqlite3_column_count".
  96.  
  97.      MOVE SPACES                  TO FUNCIONES-SQLITE3-LIB.
  98.      MOVE "sqlite3_column_count"  TO FUNCIONES-SQLITE3-LIB.    
  99.  
  100.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  101.               USING        BY VALUE   stmt-handle
  102.                            returning  BD-COLUMNA-CANTIDAD
  103.  
  104.      end-call.          
  105.  
  106. *     DISPLAY "BD-COLUMNA-CANTIDAD : " , BD-COLUMNA-CANTIDAD.
  107.  
  108. *-------------------------------------------------------------------------
  109.  DB-STEP.
  110. *-------------------------------------------------------------------------
  111. *>sqlite3_step
  112. *    DISPLAY "--------------------".
  113. *    DISPLAY "sqlite3_step".
  114.  
  115.      MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
  116.      MOVE "sqlite3_step"          TO FUNCIONES-SQLITE3-LIB.    
  117.  
  118.      call     FUNCIONES-SQLITE3-LIB  WITH STDCALL LINKAGE
  119.               USING        BY VALUE   stmt-handle
  120.                            returning  BD-STATUS
  121.  
  122.      end-call.      
  123. *    DISPLAY BD-STATUS.    
  124.      
  125.  
  126.  
Saludos ...


Muchas gracias. Tu ayuda ha sido muy importante.
Mi ultima duda es como convertir un puntero en texto o una fecha o un campo numerico o incluso un "BLOB",
ser consultable en powercobol.

ejemplo:

Código COBOL:
  1.           evaluate  BD-COLUMNA-TIPO
  2.              when 3
  3.                 call "sqlite3_column_text" & X"00" WITH  STDCALL  LINKAGE
  4.                             using
  5.                                  by value stmt-handle,
  6.                                  by value BD-COLUMNA-NUMERO
  7.                                  returning TEXT-POINTER
  8.                 end-call
  9.           end-evaluate


Saludos
José

fastpho 16 de mayo de 2023 19:59

Hola @Joseg con respecto a los tipos de datos
yo estoy trabajando en Android(B4A) con:

Código COBOL:
  1.       88  SQL_INTEGER         VALUE 1.  
  2.       88  SQL-REAL               VALUE 2.  
  3.       88  SQL_TEXT              VALUE 3.  

*Tema: Tipo dato Entero*

Para pwcobol es un PIC 9(1...13) dependiendo el uso.
Código COBOL:
  1. evaluate  BD-COLUMNA-TIPO
  2.              when 1
  3.                 perform DB-COLUMNA-INT
  4.  end-evaluate
  5.  
  6.  DB-COLUMNA-INT.
  7. *>Columna tipo Integer
  8.      MOVE SPACES               TO FUNCIONES-SQLITE3-LIB.
  9.      MOVE "sqlite3_column_int" TO FUNCIONES-SQLITE3-LIB.
  10.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  11.              USING        BY VALUE   BD-HANDLE-STMT
  12.                           BY VALUE   BD-COLUMNA-NUMERO
  13.                           returning  BD-INT
  14.      end-call.          
  15.     *>DEVUELVE BD-INT.

*Tema : Tipo de dato Fecha*
en Android represento las fechas en ticks(type Long)

Código VB:
  1. DateTime.DateFormat="dd-MM-yyyy"
  2. Dim SomeTime As Long
  3. SomeTime = DateTime.DateParse("16/05/2023")
Para sqlite es un SQL_INTEGER (SomeTime)
Para pwcobol la paso a PIC X(13) (SomeTime)

Código COBOL:
  1. LINKAGE SECTION.
  2.  01  sqlite3-value-text     PIC X(256).
  3.  
  4.  evaluate  BD-COLUMNA-TIPO
  5.              when 3 *>Date Ticks
  6.                perform DB-COLUMNA-TEXT
  7.  end-evaluate
  8.  
  9.  DB-COLUMNA-TEXT.
  10.     *>Columna tipo TEXT
  11.      MOVE SPACES                TO FUNCIONES-SQLITE3-LIB.
  12.      MOVE "sqlite3_column_text" TO FUNCIONES-SQLITE3-LIB.
  13.      MOVE SPACES          TO BD-TEXT.
  14.      call     FUNCIONES-SQLITE3-LIB WITH  STDCALL  LINKAGE
  15.              USING        BY VALUE   BD-HANDLE-STMT
  16.                           BY VALUE   BD-COLUMNA-NUMERO
  17.                           returning  BD-TEXT-POINTER
  18.      end-call.          
  19.      SET ADDRESS OF sqlite3-value-text TO BD-TEXT-POINTER.
  20.      STRING
  21.             sqlite3-value-text delimited by low-value
  22.             into BD-TEXT
  23.      END-STRING.
  24.      SET  BD-TEXT-POINTER TO NULL.
  25.     *>DEVUELVE BD-TEXT.

*Tema : Tipo de dato Real*
Tambien lo trato con sqlite3_column_text y lo muevo a
Código COBOL:
  1.  01 importe-text   pic X(13)
y luego lo convierto a numerico

Código COBOL:
  1.     evaluate  BD-COLUMNA-TIPO
  2.              when 2 *>Real
  3.                perform DB-COLUMNA-TEXT
  4.       end-evaluate

*Tema : Tipo de dato Blob*

No lo he implementado en android
Pero creo que lo mejor es guardar la direccion de la
imagen fisica del archivo de la memoria del celular o
mobil y no la imagen como tal.

*Tema : Tipo de dato Text*

simplemente como text PIC X(1...256)

Espero que te ayude y se entienda.
Saludos...

Joseg 17 de mayo de 2023 16:44

Gracias por la ayuda. Todo está funcionando ahora. :bat::bat::bat:

Abrazo.
José

Nitzer 17 de mayo de 2023 17:56

El problema de todo esto, es la cantidad de código y lo poco explícito que parece para acceder a los datos.
YO ya os dije que utilizo un activex que me hicieron para acceder y ejecutar y es tremendamente sencillo y claro.

Llevo muchos años trabajando practicamente solo con bases de datos y estoy encantado :)

Joseg 18 de mayo de 2023 00:01

Cita:

Citación del post de Nitzer (Mensaje 8914)
El problema de todo esto, es la cantidad de código y lo poco explícito que parece para acceder a los datos.
YO ya os dije que utilizo un activex que me hicieron para acceder y ejecutar y es tremendamente sencillo y claro.

Llevo muchos años trabajando practicamente solo con bases de datos y estoy encantado :)

No encontré ningún OCX con posibilidad de conectarse a la Base de Datos (pero sería interesante)..
La idea de acceder a SQLITE directamente, sin ODBC, es facilitar la instalación de la aplicación por parte de "no informáticos".

Nitzer 18 de mayo de 2023 10:16

Cita:

Citación del post de Joseg (Mensaje 8915)
No encontré ningún OCX con posibilidad de conectarse a la Base de Datos (pero sería interesante)..
La idea de acceder a SQLITE directamente, sin ODBC, es facilitar la instalación de la aplicación por parte de "no informáticos".

@Joseg, no se que pasó en mi anterior mensaje, se me cortó toda la parte final del mismo. Se ha quedado un texto que parece que esté regañando ajajajajaj

En algún mensaje expliqué como empecé con las bases de datos en Power.
Ya sabemos que power tiene varios controles para ello, el primero DbAccess, es por donde empecé para ir comprendiendo , pero pronto te das cuenta que no es lo que buscas.
Luego continué con sql embebido y la configuración de cobol85, que tampoco me terminaba de convencer, aunque hacía su función.
Lo siguiente y con lo que mas he estado ha sido utilizado el control ADO, con ese casi todo lo puedes hacer, la pena es que no hay mucha información enPower, pero a fin de cuentas es ADO, y de ado hay muuuuucha información en internet, empecé a ver todos los métodos, funciones, etc ... y aplicarlas en power, unas iban bien y otras no , me quedé con las que funcionaban y así he estado varios años completamente satisfecho.

Pero mi interés por la sql seguía creciendo y necesitaba aplicar consultas mas grandes, procedimientos almacenados, funciones, etc ... en ese momento empecé a buscar por internet, pero no encontré gran cosa.
Pero conocía a una empresa que tenía varios ocx y con la que ya había contactado , la empresa es FathSowtware, que por cierto hace unos meses cerró y ya no hay manera de encontrar sus productos, pero Admir que es quien llevaba la empresa, lo había conocido e intercamabiado correos, así que le dije si me podía hacer un activex para acceder nativamente a sqlserver y .... tras 27 prototipos y 200 dolares , conseguí lo que buscaba :)

Desde entonces todo ha cambiado.
Si queréis le puedo preguntar si estaría dispuesto a venderlo o regalarlo o lo que sea, es un ocx sencilla,se registra y se distribuye y por ahora y tras varios años, todo perfecto.

Y siento si el mensaje anterior se malinterpretó, admiro el trabajo de cada uno de vosotros.

Joseg 18 de mayo de 2023 11:40

Todo bien.
Estamos aquí para ayudarnos unos a otros.
Este OCX parece interesante, pero comprar un producto aparentemente descatalogado no sería buena idea. Como producto gratuito/de código abierto, me gustaría probarlo.

Saludos


La franja horaria es GMT +2. Ahora son las 15:44.

Powered by: vBulletin, Versión 3.8.7
Derechos de Autor ©2000 - 2026, Jelsoft Enterprises Ltd.