PDA

Ver la Versión Completa : [PowerCOBOL] SQlite3 con PowerCobol


fastpho
28 de abril de 2023, 13:22
Permite integrar el motor de base de datos de SQlite con nuestras aplicaciones.
En mi caso es para poder interactuar con una aplicacion que hice para Android
y poder leer la informacion de la BD y evitar utilizar archivos con formato .CSV
como interface.
Su implementacion es muy sencilla descargar Binarios precompilados
para Windows para su version 32 bits (sqlite3.dll) no hace falta registrarla.

1 - Copiar Sqlite3.dll en la carpeta del proyecto
2 - Agregar la funciones de la libreria en el Archivo COBOL85
3 - Luego llamar a esas funciones via call
4 - Informacion de las funciones en : https://sqlite.org/c3ref/funclist.html

Ejemplo para abrir , crear , insertar , actualizar un registro y cerrar

Declaracion Variables

01 BD-HANDLE PIC 9(9) COMP-5 IS GLOBAL. *>Handle de la BD
01 BD-FILE-NAME PIC X(50) IS GLOBAL. *>Nombre de la BD
01 BD-SQL-QUERY PIC X(256) IS GLOBAL. *>string sql (Create , Insert , Delete , Update , Select)
01 BD-SQL-STRING-LENGHT PIC S9(9) COMP-5 IS GLOBAL.
01 BD-HANDLE-STMT PIC 9(9) COMP-5 IS GLOBAL. *>Puntero Statement
01 BD-STMT-PTR REDEFINES BD-HANDLE-STMT POINTER IS GLOBAL. *>Redefines del Puntero Statement

01 BD-INT-POINTER POINTER IS GLOBAL.
01 BD-INT PIC 9(9) COMP-5 IS GLOBAL. *> INTEGER
01 BD-DOB PIC 9(9) COMP-5 IS GLOBAL. *> DOUBLE

01 BD-TEXT-POINTER POINTER IS GLOBAL.
01 BD-TEXT PIC X(256) IS GLOBAL. *> TEXT
01 BD-SQL-ERROR POINTER IS GLOBAL.


01 BD-FILA-ID PIC 9(9) COMP-5 IS GLOBAL.
01 BD-COLUMNA-CANTIDAD PIC 9(9) COMP-5 IS GLOBAL.
01 BD-COLUMNA-NUMERO PIC 9(9) COMP-5 IS GLOBAL.
01 BD-COLUMNA-NOMBRE PIC X(256) IS GLOBAL.
01 BD-COLUMNA-POINTER POINTER IS GLOBAL.


* Estado de la Base de Datos
01 BD-STATUS PIC 9(9) COMP-5 IS GLOBAL.
*>Estado de la BD
01 ESTADOS-BD IS GLOBAL.
03 SQLITE_OK PIC 9(9) COMP-5 VALUE 0. *> /* Successful result */
03 SQLITE_ERROR PIC 9(9) COMP-5 VALUE 1. *> /* Generic error */
03 SQLITE_BUSY PIC 9(9) COMP-5 VALUE 5. *> /* The database file is locked */
03 SQLITE_LOCKED PIC 9(9) COMP-5 VALUE 6. *> /* A table in the database is locked */
03 SQLITE_READONLY PIC 9(9) COMP-5 VALUE 8. *> /* Attempt to write a readonly database */
03 SQLITE_EMPTY PIC 9(9) COMP-5 VALUE 16. *> /* Attempt to write a readonly database */


03 SQLITE_MISUSE PIC 9(9) COMP-5 VALUE 21. *> /* Library used incorrectly */
03 SQLITE_WARNING PIC 9(9) COMP-5 VALUE 28. *> /* unusual and possibly ill-advised operation is taking place.*/

03 SQLITE-ROW PIC 9(9) COMP-5 VALUE 100. *> /* sqlite3_step() has another row ready */
03 SQLITE-DONE PIC 9(9) COMP-5 VALUE 101. *> /* sqlite3_step() has finished executing */
* Tipos de Datos sqlite
01 BD-COLUMNA-TIPO PIC 9(4) COMP-5 IS GLOBAL.
88 SQL-INTEGER VALUE 1. *>
88 SQL-REAL VALUE 2. *>
88 SQL-TEXT VALUE 3. *>
88 SQL-BLOB VALUE 4. *>
88 SQL-NULL VALUE 5. *>


01 FECHA-CONVERTIR PIC 9(8) IS GLOBAL. *> AAAAMMDD a Convertir
01 FECHA-CONVERTIDA-UNIX PIC 9(13) IS GLOBAL. *> Fecha con formato unix
01 FECHA-UNIX1970 PIC S9(9) COMP-5 IS GLOBAL. *> desde AAAAMMDDD 19700101
01 FECHA-INT PIC S9(9) COMP-5 IS GLOBAL.
01 FECHA-AMD PIC 9(8) IS GLOBAL.
01 FECHA-AMD-ED PIC XXXX/XX/XX IS GLOBAL.

01 NULO PIC 9(9) COMP-5 VALUE 0 IS GLOBAL. *> NULO

*>https://sqlite.org/cintro.html
*>Funciones de la libreria sqlit3.dll
*>https://sqlite.org/c3ref/funclist.html
*>Funciones Declaradas en el archivo COBOL85.CBR
*>Fecha 17-04-2023
01 FUNCIONES-SQLITE3-LIB PIC X(50) IS GLOBAL.
*> sqlite3-connection functions
*> sqlite3_libversion (OUT <text>) *> Devuelve la versión de sqlite a través del parámetro OUT. OK probado
*> sqlite3_libversion_number (OUT <int> ) *> Devuelve el número de versión como un int OK probado
*> sqlite3_open (<nombre de archivo>, OUT <controlador de la base de datos>). *> Esto abre un archivo de base de datos SQLite , nueva o existente como se especifica en el argumento de nombre de archivo.OK probado
*> sqlite3_close (<db-handle>)(<identificador de la base de datos>) *> Destructor de la interface , cierra la BD OK probado
*> sqlite3_exec (<gestor-bd>,<cadena-sql>) *> Es una envoltura sqlite3_prepare_v2(), sqlite3_step() y sqlite3_finalize() OK probado
*> sqlite3_errmsg (<db-handle>, OUT <mensaje de error) *> Devuelve texto en inglés como un parámetro OUT que describe el último error en la conexión. OK probado

*> sqlit3-statement functions
*> sqlite3_prepare_v2 *>Constructor OK probado
*> sqlite3_finalize *>Destructor OK probado
*> Pass
*> sqlite3_step int sqlite3_step(sqlite3_stmt*); OK probado
*> sqlite3_reset int sqlite3_reset(sqlite3_stmt *pStmt); OK probado
*> sqlite3_finalize int sqlite3_finalize(sqlite3_stmt *pStmt); OK probado

*> Statement column access (0-base indices)
*> sqlite3_column_count int sqlite3_column_count(sqlite3_stmt *pStmt); OK probado
*> sqlite3_column_type int sqlite3_column_type(sqlite3_stmt*, int iCol); OK probado
*> sqlite3_column_name const char *sqlite3_column_name(sqlite3_stmt*, int N); OK probado
*> Statement column type
*> sqlite3_column_int int sqlite3_column_int(sqlite3_stmt*, int iCol); OK probado
*> sqlite3_column_text const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); OK probado
*> sqlite3_column_double double sqlite3_column_double(sqlite3_stmt*, int iCol); OK probado
*> sqlite3_column_blob no implementado




Abrir BD


*------------------------------------------------------------------
*>sqlite3_open
* DISPLAY "------------".
* DISPLAY "sqlite3_open".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_open" TO FUNCIONES-SQLITE3-LIB.
MOVE "datos.db" & X"00" TO BD-FILE-NAME.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY REFERENCE BD-FILE-NAME
BY REFERENCE BD-HANDLE
returning BD-STATUS

end-call.
IF BD-STATUS NOT = SQLITE_OK THEN
CALL "BD-ERROR"
ELSE
MOVE "OK" TO "Caption" OF CmStatic2
END-IF.


Crear BD


*------------------------------------------------------------------
*>sqlite3_exec
* DISPLAY "------------".
* DISPLAY "sqlite3_exec".
* DISPLAY "CREATE".
MOVE SPACES TO BD-SQL-QUERY.
MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_exec" TO FUNCIONES-SQLITE3-LIB.
MOVE "CREATE TABLE usuarios (id INTEGER PRIMARY KEY AUTOINCREMENT , nombre TEXT , edad INTEGER )" & X"00" TO BD-SQL-QUERY.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING
BY VALUE BD-HANDLE
BY CONTENT BD-SQL-QUERY
BY VALUE 0
BY VALUE 0
BY VALUE 0
returning BD-STATUS

end-call.


IF BD-STATUS NOT = SQLITE_OK THEN
CALL "BD-ERROR"
ELSE
MOVE "OK" TO "Caption" OF CmStatic2
END-IF.



Insertar Registro BD


*------------------------------------------------------------------
*>sqlite3_exec
* DISPLAY "------------------".
* DISPLAY "sqlite3_exec".
* DISPLAY "INSERT".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_exec" TO FUNCIONES-SQLITE3-LIB.

MOVE SPACES TO BD-SQL-QUERY.
string "INSERT INTO usuarios (nombre , edad ) " delimited by size
" VALUES ('Leonardo' , 24 )" delimited by size
x"00" delimited by size
into BD-SQL-QUERY
end-string.


call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING
BY VALUE BD-HANDLE
BY CONTENT BD-SQL-QUERY
BY VALUE 0
BY VALUE 0
BY VALUE 0
returning BD-STATUS

end-call.
IF BD-STATUS NOT = SQLITE_OK
CALL "BD-ERROR"
END-IF.


Actualizar Registro BD

PROCEDURE DIVISION.
*------------------------------------------------------------------
*>sqlite3_exec
* DISPLAY "------------------".
* DISPLAY "sqlite3_exec".
* DISPLAY "UPDATE".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE SPACES TO BD-SQL-QUERY.
MOVE "sqlite3_exec" TO FUNCIONES-SQLITE3-LIB.


string "UPDATE usuarios SET nombre = 'xxxx' " delimited by size
" WHERE id = 1" delimited by size
x"00" delimited by size
into BD-SQL-QUERY
end-string.


call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING
BY VALUE BD-HANDLE
BY CONTENT BD-SQL-QUERY
BY VALUE 0
BY VALUE 0
BY VALUE 0
returning BD-STATUS

end-call.

IF BD-STATUS NOT = SQLITE_OK
CALL "BD-ERROR"
ELSE
MOVE "OK" TO "Caption" OF CmStatic2
END-IF.



Cerar BD

*------------------------------------------------------------------
*>sqlite3_close
* DISPLAY "------------".
* DISPLAY "sqlite3_close".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_close" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE BD-HANDLE
returning BD-STATUS

end-call.

IF BD-STATUS NOT = SQLITE_OK THEN
CALL "BD-ERROR"
ELSE
MOVE "OK" TO "Caption" OF CmStatic2
END-IF.



Saludos....

Joseg
28 de abril de 2023, 15:26
Muito interessante!
Obrigado

Josber
28 de abril de 2023, 17:05
Gracias @fastpho, lo único que recomiendo encarecidamente cuando se trabaja con BDs, es que los nombre de las variables que usemos para esas BDs, no contengan el guion medio (-), y sí el guion bajo (_), esto es porque sql, lo puede confundir con el signo de restar (-), el programa puede hacer cosas inesperadas y te vuelves loco buscando el error, (por experiencia propia). Aquí, no parece que se vaya a dar la condición, pero, no es malo, coger esa costumbre. Sólo hay que fijarse en las variables propias de sql, en las que todas son SQLITE_xxxx, y no SQLITE-xxxx

Por lo demás, un excelente aporte

Un salu2.-

fastpho
28 de abril de 2023, 17:35
Gracias @Josber , voy a tomar la sugerencia para evitar posibles problemas
Saludos....

luisbago
28 de abril de 2023, 20:05
un idx2sqlite seria fabuloso, así se traslada datos sin intermediarios

Joseg
2 de mayo de 2023, 12:49
Gracias @Josber , voy a tomar la sugerencia para evitar posibles problemas
Saludos....

O mesmo exemplo, mas usando o Sqlit3.Lib. Não necessita de cobol85.cbr

Para criar o .LIB na mesma pasta a onde esta o SQLITE3.DLL
Linha de comandos: lib /DEF:sqlite3.def /OUT:sqlite3.lib /MACHINE:x32 (ou x64)

Joseg
12 de mayo de 2023, 12:37
Hola,

Como implementar un loop en PowerCobol?

Ejemplo de lista de todos los registros de "MyTable":
select * from MyTable

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

... pero no lo estoy consiguiendo.

Gracias,
Jose

fastpho
12 de mayo de 2023, 13:49
Hola @Joseg

Para poder realizar un "select" yo no lo pude hacer por "CALLBACK"
trabajo con la version 5.0 de PowerCobol y no acepta PROCEDURE-POINTER
Entonces para resolverlo hago :

sqlite3_open_v2
sqlite3_prepare_v2

sqlite3_step aca hay que meter el loop si SQLITE_ROW o SQLITE_DONE

sqlite3_finalize
sqlite3_close_v2
Saludos...

Joseg
12 de mayo de 2023, 18:39
Hola @Joseg

Para poder realizar un "select" yo no lo pude hacer por "CALLBACK"
trabajo con la version 5.0 de PowerCobol y no acepta PROCEDURE-POINTER
Entonces para resolverlo hago :

sqlite3_open_v2
sqlite3_prepare_v2

sqlite3_step aca hay que meter el loop si SQLITE_ROW o SQLITE_DONE

sqlite3_finalize
sqlite3_close_v2
Saludos...

Muchas gracias :)

Pero, sigue sin funcionar :(


working-storage.
01 num-bytes pic s9(09) COMP-5 IS GLOBAL.
01 num-columns pic s9(09) COMP-5 IS GLOBAL.
01 pStmt usage pointer IS GLOBAL.
01 zTail pic s9(09) COMP-5 IS GLOBAL.

procedure division.

MOVE "chinook.db" & X"00" TO BD-FILE-NAME.

call "sqlite3_open_v2" & X"00" WITH STDCALL LINKAGE
USING BY REFERENCE BD-FILE-NAME
BY REFERENCE BD-HANDLE
BY VALUE 2 *> SQLITE_OPEN_READWRITE
BY VALUE 0
returning BD-STATUS

end-call.

string "SELECT * from artists WHERE name='Body Count' " delimited by size
X"00" delimited by size
into BD-SQL-QUERY
WITH POINTER num-bytes.

move zero to zTail

call "sqlite3_prepare_v2" & X"00" WITH STDCALL LINKAGE
USING
BY VALUE BD-HANDLE
BY CONTENT BD-SQL-QUERY
BY VALUE num-bytes
by reference pStmt
by VALUE zTail
returning BD-STATUS

end-call.

*loop
call "sqlite3_step" & X"00" WITH STDCALL LINKAGE
using
by reference pStmt
returning BD-STATUS
end-call.

evaluate ESTADOS-BD
when SQLITE-ROW
display "SQLITE-ROW"
when SQLITE-DONE
display "SQLITE-DONE"
end-evaluate



¿Qué tiene de malo esta parte del código?
call "sqlite3_step" da el error
SQLITE_MISUSE = 21. *> Library used incorrectly

Powercobol v9
Gracias,
José

fastpho
12 de mayo de 2023, 20:13
@Joseg
La funcion sqlite3_step espera el valor por value no por reference seria asi :

working-storage.
01 stmt-handle PIC 9(9) COMP-5.
01 redefines stmt-handle.
05 pStmt usage pointer.





call "sqlite3_step" & X"00" WITH STDCALL LINKAGE
using by value stmt-handle
returning BD-STATUS
end-call


Saludos...

Josber
13 de mayo de 2023, 14:06
Hola,

Como implementar un loop en PowerCobol?

Ejemplo de lista de todos los registros de "MyTable":
select * from MyTable

Creo que tienes que usar "sqlite3_prepare" y "sqlite3_step", o implementar una "devolución de llamada" (callback),
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í:


EXEC SQL
DECLARE cursor_consulta CURSOR FOR
SELECT * FROM CLIENTES
WHERE .....
ORDER BY .....
END-EXEC.

INITIALIZE SQLSTATE.

EXEC SQL
OPEN cursor_consulta
END-EXEC.

PERFORM WITH NO LIMIT
EXEC SQL
FETCH cursor_consulta
INTO .....
END-EXEC
IF SQLSTATE = "02000"
EXEC SQL
CLOSE cursor_consulta
END-EXEC
EXIT PERFORM
END-IF
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
@Joseg
La funcion sqlite3_step espera el valor por value no por reference seria asi :

working-storage.
01 stmt-handle PIC 9(9) COMP-5.
01 redefines stmt-handle.
05 pStmt usage pointer.





call "sqlite3_step" & X"00" WITH STDCALL LINKAGE
using by value stmt-handle
returning BD-STATUS
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)

move 1 to wnum-columns
call "sqlite3_column_type" & X"00" WITH STDCALL LINKAGE
using
by value stmt-handle
by value wnum-columns
returning BD-COLUMNA-TIPO
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

*-------------------------------------------------------------------------
*>STEP
*-------------------------------------------------------------------------
DISPLAY "------------------".
DISPLAY "sqlite3_step ".

PERFORM DB-STEP.
evaluate bd-status
when SQLITE_ROW
perform muestro-cabecera
when SQLITE_DONE
display "termino"
continue
when other
display "error"
exit program
end-evaluate.
*-------------------------------------------------------------------------
*>FINALIZE
*-------------------------------------------------------------------------
DISPLAY "------------------".
DISPLAY "sqlite3_finalize".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_finalize" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
returning BD-STATUS

end-call.

IF BD-STATUS NOT = SQLITE_OK then
DISPLAY "ERROR "

ELSE
DISPLAY "OK"
END-IF.
*-------------------------------------------------------------------------
*>CLOSE_V2
*-------------------------------------------------------------------------
DISPLAY "------------------".
DISPLAY "sqlite3_close_v2".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_close_v2" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE BD-HANDLE
returning BD-STATUS

end-call.

IF BD-STATUS NOT = SQLITE_OK then
CALL "BD-ERROR"
EXIT PROGRAM
ELSE
DISPLAY "OK"
END-IF.


EXIT PROGRAM.

*-------------------------------------------------------------------------
MUESTRO-CABECERA.
*-------------------------------------------------------------------------

PERFORM DB-CANTIDAD-COLUMNAS.

MOVE ZEROS TO BD-COLUMNA-NUMERO.
PERFORM VARYING BD-COLUMNA-NUMERO FROM 0 BY 1 UNTIL BD-COLUMNA-NUMERO = BD-COLUMNA-CANTIDAD
*>sqlite3_column_type
* DISPLAY "--------------------"
* DISPLAY "sqlite3_column_type"

MOVE SPACES TO FUNCIONES-SQLITE3-LIB
MOVE "sqlite3_column_type" TO FUNCIONES-SQLITE3-LIB

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
BY VALUE BD-COLUMNA-NUMERO *> COMIENZA DE 0 LAS COLUMNAS HASTA sqlite3_column_count - 1
returning BD-COLUMNA-TIPO *> RETORNA EL TIPO DE COLUMNA
end-call

DISPLAY "--------------------"
DISPLAY " COL NRO : " , BD-COLUMNA-NUMERO , " es COLUMNA-TIPO " , BD-COLUMNA-TIPO
DISPLAY "--------------------"
END-PERFORM.

*-------------------------------------------------------------------------
DB-CANTIDAD-COLUMNAS.
*-------------------------------------------------------------------------
*>sqlite3_column_count
* DISPLAY "--------------------".
* DISPLAY "sqlite3_column_count".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_column_count" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
returning BD-COLUMNA-CANTIDAD

end-call.

* DISPLAY "BD-COLUMNA-CANTIDAD : " , BD-COLUMNA-CANTIDAD.

*-------------------------------------------------------------------------
DB-STEP.
*-------------------------------------------------------------------------
*>sqlite3_step
* DISPLAY "--------------------".
* DISPLAY "sqlite3_step".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_step" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
returning BD-STATUS

end-call.
* DISPLAY BD-STATUS.





Saludos ...

Joseg
16 de mayo de 2023, 17:48
Hola @Joseg como recorrer la tabla para saber que tipo valor se puede almacenar por columnas

*-------------------------------------------------------------------------
*>STEP
*-------------------------------------------------------------------------
DISPLAY "------------------".
DISPLAY "sqlite3_step ".

PERFORM DB-STEP.
evaluate bd-status
when SQLITE_ROW
perform muestro-cabecera
when SQLITE_DONE
display "termino"
continue
when other
display "error"
exit program
end-evaluate.
*-------------------------------------------------------------------------
*>FINALIZE
*-------------------------------------------------------------------------
DISPLAY "------------------".
DISPLAY "sqlite3_finalize".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_finalize" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
returning BD-STATUS

end-call.

IF BD-STATUS NOT = SQLITE_OK then
DISPLAY "ERROR "

ELSE
DISPLAY "OK"
END-IF.
*-------------------------------------------------------------------------
*>CLOSE_V2
*-------------------------------------------------------------------------
DISPLAY "------------------".
DISPLAY "sqlite3_close_v2".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_close_v2" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE BD-HANDLE
returning BD-STATUS

end-call.

IF BD-STATUS NOT = SQLITE_OK then
CALL "BD-ERROR"
EXIT PROGRAM
ELSE
DISPLAY "OK"
END-IF.


EXIT PROGRAM.

*-------------------------------------------------------------------------
MUESTRO-CABECERA.
*-------------------------------------------------------------------------

PERFORM DB-CANTIDAD-COLUMNAS.

MOVE ZEROS TO BD-COLUMNA-NUMERO.
PERFORM VARYING BD-COLUMNA-NUMERO FROM 0 BY 1 UNTIL BD-COLUMNA-NUMERO = BD-COLUMNA-CANTIDAD
*>sqlite3_column_type
* DISPLAY "--------------------"
* DISPLAY "sqlite3_column_type"

MOVE SPACES TO FUNCIONES-SQLITE3-LIB
MOVE "sqlite3_column_type" TO FUNCIONES-SQLITE3-LIB

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
BY VALUE BD-COLUMNA-NUMERO *> COMIENZA DE 0 LAS COLUMNAS HASTA sqlite3_column_count - 1
returning BD-COLUMNA-TIPO *> RETORNA EL TIPO DE COLUMNA
end-call

DISPLAY "--------------------"
DISPLAY " COL NRO : " , BD-COLUMNA-NUMERO , " es COLUMNA-TIPO " , BD-COLUMNA-TIPO
DISPLAY "--------------------"
END-PERFORM.

*-------------------------------------------------------------------------
DB-CANTIDAD-COLUMNAS.
*-------------------------------------------------------------------------
*>sqlite3_column_count
* DISPLAY "--------------------".
* DISPLAY "sqlite3_column_count".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_column_count" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
returning BD-COLUMNA-CANTIDAD

end-call.

* DISPLAY "BD-COLUMNA-CANTIDAD : " , BD-COLUMNA-CANTIDAD.

*-------------------------------------------------------------------------
DB-STEP.
*-------------------------------------------------------------------------
*>sqlite3_step
* DISPLAY "--------------------".
* DISPLAY "sqlite3_step".

MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_step" TO FUNCIONES-SQLITE3-LIB.

call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE stmt-handle
returning BD-STATUS

end-call.
* DISPLAY BD-STATUS.





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:


evaluate BD-COLUMNA-TIPO
when 3
call "sqlite3_column_text" & X"00" WITH STDCALL LINKAGE
using
by value stmt-handle,
by value BD-COLUMNA-NUMERO
returning TEXT-POINTER
end-call
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:


88 SQL_INTEGER VALUE 1.
88 SQL-REAL VALUE 2.
88 SQL_TEXT VALUE 3.


*Tema: Tipo dato Entero*

Para pwcobol es un PIC 9(1...13) dependiendo el uso.

evaluate BD-COLUMNA-TIPO
when 1
perform DB-COLUMNA-INT
end-evaluate

DB-COLUMNA-INT.
*>Columna tipo Integer
MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_column_int" TO FUNCIONES-SQLITE3-LIB.
call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE BD-HANDLE-STMT
BY VALUE BD-COLUMNA-NUMERO
returning BD-INT
end-call.
*>DEVUELVE BD-INT.


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


DateTime.DateFormat="dd-MM-yyyy"
Dim SomeTime As Long
SomeTime = DateTime.DateParse("16/05/2023")

Para sqlite es un SQL_INTEGER (SomeTime)
Para pwcobol la paso a PIC X(13) (SomeTime)


LINKAGE SECTION.
01 sqlite3-value-text PIC X(256).

evaluate BD-COLUMNA-TIPO
when 3 *>Date Ticks
perform DB-COLUMNA-TEXT
end-evaluate

DB-COLUMNA-TEXT.
*>Columna tipo TEXT
MOVE SPACES TO FUNCIONES-SQLITE3-LIB.
MOVE "sqlite3_column_text" TO FUNCIONES-SQLITE3-LIB.
MOVE SPACES TO BD-TEXT.
call FUNCIONES-SQLITE3-LIB WITH STDCALL LINKAGE
USING BY VALUE BD-HANDLE-STMT
BY VALUE BD-COLUMNA-NUMERO
returning BD-TEXT-POINTER
end-call.
SET ADDRESS OF sqlite3-value-text TO BD-TEXT-POINTER.
STRING
sqlite3-value-text delimited by low-value
into BD-TEXT
END-STRING.
SET BD-TEXT-POINTER TO NULL.
*>DEVUELVE BD-TEXT.


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


evaluate BD-COLUMNA-TIPO
when 2 *>Real
perform DB-COLUMNA-TEXT
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
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
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

fastpho
18 de mayo de 2023, 14:50
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 :)
@Nitzer , el codigo que he subido esta crudo
para que puedan entenderlo , por eso se ve poco explicito y tantas lineas de codigo como decis...(no he malinterpretado tu mensaje) :bien:

La idea de esto es hacerle mas facil la vida (programacion) a los/las
futuros desarrolladores y sepan que con COBOL se puede hacer lo mismo
que con otros lenguajes y obtener los mismos resultados y en algunos
casos hasta mas rapido y efeciente.

Este es un lenguaje denominado de "VIEJOS" , que ya ni se enseña ,
no es un lenguaje "COOL" , pero hay que tratar de llevar a la
juventud a creer en el.

No voy a seguir delirando .....

Volviendo al tema sqlite , es muy simple su implementacion como explique
en el post nro 1

Lo que he echo es envolver la funciones del libreria(sqlite3.dll) de tal forma que queda exactamente igual a cualquier llamada por (invoke o call)
de un activex (dll o ocx) y evitar tantas lineas de codigo.


Saludos....

Nitzer
19 de mayo de 2023, 09:55
@fastpho, siento el mensaje :(, os juro que no iba con mala intención.

He hablado con la persona que me hizo el ocx y me ha dicho que lo puedo distribuir libremente.

He pensado en hacer un pequeño video explicando como lo utilizo, un pequeño manual con los métodos y os voy pasado el ocx a quien lo quiera. El ocx pesa 2 mb

Decidme si merece la pena.

Joseg
19 de mayo de 2023, 11:10
@fastpho, siento el mensaje :(, os juro que no iba con mala intención.

He hablado con la persona que me hizo el ocx y me ha dicho que lo puedo distribuir libremente.

He pensado en hacer un pequeño video explicando como lo utilizo, un pequeño manual con los métodos y os voy pasado el ocx a quien lo quiera. El ocx pesa 2 mb

Decidme si merece la pena.

Estaria interesado.
Puedes usar Mega para subir (u otro).

Gracias

Kuk
19 de mayo de 2023, 11:12
@Nitzer, puedes subirlo al foro directamente ;)

fastpho
19 de mayo de 2023, 13:38
@fastpho, siento el mensaje :(, os juro que no iba con mala intención.

He hablado con la persona que me hizo el ocx y me ha dicho que lo puedo distribuir libremente.

He pensado en hacer un pequeño video explicando como lo utilizo, un pequeño manual con los métodos y os voy pasado el ocx a quien lo quiera. El ocx pesa 2 mb

Decidme si merece la pena. :sis:
@Nitzer
Seria muy bueno que puedas compartir la ocx ;)
Muchas gracias

Fito
20 de mayo de 2023, 16:29
Hola:

Estoy muy interesado Andrés. Te estaba persiguiendo por discord por ese tema :mola:

Saludos

Fito

Joseg
30 de mayo de 2023, 11:34
:astro:
el OCX fue compartido?!