Ir al contenido



Foto

Conexion con BB.DD sqlite


  • Por favor identifícate para responder
90 respuestas en este tema

#21 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.890 mensajes
  • LocationArgentina

Escrito 15 marzo 2016 - 10:04

Pues me han confirmado que no tengo que hacer un viajecito mañana temprano asi que puse manos a la obra y hice unas pruebas sencillas para un "demo".

He descargado SQLite-3 en 64bits (es el bitness de mi equipo y SO) e hice unas pruebas.

 

Entorno de trabajo:

Windows 8.1 64bits

CodeTyphon 5.6

* Fecha: 2016-01-18

* FPC: 3.1.1

* Revision SVN: 50892

 

SQLite 3 64bits

Zeos versión 7.2.0-beta (el que viene por defecto instalado en CT)

 

Mecánica de trabajo, inspirada en el tutorial que nos pasaste:

 

1. Descargar el .zip de la dll 64bits de SQLite3. Descomprimir y copiar los dos archivos (la .dll y el archivo .def) tanto en C:\Windows\ (Lo necesita Lazarus para trabajar desde el IDE) y en el directorio del proyecto y el exe

2. Crear un nuevo proyecto en Lazarus, disponer de un nuevo TDataModule.

3. En el DataModule puse lo necesario: un TZConnection, un TZQuery, y un TZTable.

4. Configurar la conexión:

4.1. Indicamos la ruta de la base de datos. Es decir el directorio del proyecto

4.2. Establecemos en la propiedad LibraryLocation la ruta hacia la dll (la del proyecto)

4.3. En Protocol le establecemos que sea sqlite-3

5. Enlazamos el query y el table hacia la conexión. Por ahora nada más.

 

Ahora en el form dispuse de botones para conectarse, crear la tabla, insertar, etc. Y para comprobar de que las operaciones de inserción se realizan perfectamente dispuse de un TDBGrid y un TDataSource. Vinculamos el Grid al DataSource.

Dejamos por el momento al TDataSource sin conectar a ningún DataSet. Ya verás por qué.

 

Y luego empecé a dar forma al código.

Advierto que siguiendo mis sospechas, he basado mi código fuertemente bajo el concepto de las transacciones. Es una forma muy segura de proceder y te recomiendo que la vayas aplicando.

La creación de la tabla la efectué con el TZQuery, con la instrucción exactamente igual a la que nos describes.

 

Leyendo el comentario de Agustín por el "main"."personas" pensé ¿Y no será que por haber indicado "main" debemos anteponer esto al momento de insertar? Asi que aprovechando el mismo Query lo cierro y en otro botón procedo a efectuar una inserción por la vía SQL. La consulta adquiere entonces esta forma:


sql
  1. INSERT INTO "main"."personas"("nombre","edad") VALUES (:elnombre, :laedad)

Le mando un .ExecSQL, confirmo la transacción todo dentro de un try-except para que en caso de que exista un error poder capturar el mensaje y ver si hay algún problema. No hay aviso de error. Asi que supuse que todo estaba en orden.

 

Para sacar la duda procedo a enlazar el DataSource al Query, e implemento en otro botón una consulta como esta:


sql
  1. SELECT * FROM "main"."personas"

Y el Grid muestra, confirmando, que todo funcionó.

 

Confirmo la operación, cierro el Grid, vuelvo a insertar otro más, vuelvo a mostrar y ahora tengo 2 registros.

 

Por esta exitosa prueba, tengo mi sospecha y todo se debe a que tu indicaste como eschema el "main". Si no te muestra nada es porque no en realidad no hay nada en tabla. Mi teoría es que para el TZTable en el nombre de la tabla deberás asignarle justamente main.personas. Ya es tarde para mi, pero luego puedo continuar haciendo pruebas. Por el momento puedes probar mi teoria, prueba anteponiendo main al nombre de la tabla en tu TZTable.

Para comprobar si la tabla tiene elementos, haz una consulta SELECT * con el mismo query u otro y enlaza el Grid a ésta. Si te muestra algo, tiene sino no hay nada. Por código también es posible... que yo recuerde tanto TZQuery como TZTable tienen la función .IsEmpty que regresa true si efectivamente están vacios. Prueba y dinos.

 

Ni bien tenga más tiempo y termine la "demo" la subo al foro con el código. Creería que con los comentarios que puse se entenderá el código, y aprenderás nuevas cosas: el uso de transacciones y te invitaré un desconocido: las excepciones. Ambas cosas te ayudarán a subir unos peldaños en tu formación ;)

 

Saludos,


  • 0

#22 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 250 mensajes

Escrito 16 marzo 2016 - 02:09

No comprendo como siguiendo el mismo tutorial ahora no me funcione, con dichas instrucciones.

 

Como bien me indica Delphius, sobre el tema de controlar errores etc al trabajar con la BB.DD y ya me van sonando algo, porque vi algo cuando funcionaba dicho codigo en mi anterior equipo con XP. Ese paso será el siguiente como tengo pensado una vez consiga crear la tabla e insertar datos en ella correctamente...

 

Estoy bloqueado con este tema, ya que por más de mil vueltas que le doy y cambio sentencias, ya me "saltan" todo tipo de errores al compilar.

Mi intención es buscar la forma más didáctica posible para seguir complementándolo con vuestro consejos y tutoriales que puedo seguir, para llevar un orden.

 

Gracias a todos por vuestra inestimable ayuda y sobre todo a mi colega Delphius por su dedicación y predisposición en cada duda

de principiante.

 

Un pequeña confesión personal que quiero compartir con vosotros es que siempre quise dominar un lenguaje visual y desarrollar aplicaciones "de peso", y creo haber encontrado el foro y el software necesario para lograrlo, es un gran reto que tuve desde hace muchos y digo muchos años, pero el tiempo y la falta de medios me lo impedían.

 

saludos


  • 2

#23 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.500 mensajes
  • LocationMéxico

Escrito 16 marzo 2016 - 02:27

No comprendo como siguiendo el mismo tutorial ahora no me funcione, con dichas instrucciones.
 
Como bien me indica Delphius, sobre el tema de controlar errores etc al trabajar con la BB.DD y ya me van sonando algo, porque vi algo cuando funcionaba dicho codigo en mi anterior equipo con XP. Ese paso será el siguiente como tengo pensado una vez consiga crear la tabla e insertar datos en ella correctamente...
 
Estoy bloqueado con este tema, ya que por más de mil vueltas que le doy y cambio sentencias, ya me "saltan" todo tipo de errores al compilar.
Mi intención es buscar la forma más didáctica posible para seguir complementándolo con vuestro consejos y tutoriales que puedo seguir, para llevar un orden.
 
Gracias a todos por vuestra inestimable ayuda y sobre todo a mi colega Delphius por su dedicación y predisposición en cada duda
de principiante.


Hola
 
Cuando uno se bloquea de tantas "modificaciones" lo mejor es comenzar de cero, una forma limpiecita y va de nuevo. (y)
 

Un pequeña confesión personal que quiero compartir con vosotros es que siempre quise dominar un lenguaje visual y desarrollar aplicaciones "de peso", y creo haber encontrado el foro y el software necesario para lograrlo, es un gran reto que tuve desde hace muchos y digo muchos años, pero el tiempo y la falta de medios me lo impedían.

 
Nunca es tarde para comenzar, ahora que puedes adelante, DelphiAccess tiene sus puertas abiertas y tiene compañeros que realmente valen su peso en oro. (y)

 

Saludos


  • 0

#24 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.135 mensajes
  • LocationRepública Dominicana

Escrito 16 marzo 2016 - 02:34

Vamos por parte, acabo de probarlo con Lazarus y me funciona perfecto:

Creamos:

1) DataModule1 (En este tuto se llamará Unit2);
2) Form1 (En este tuto se llamará Unit1);

En el DataModule1 colocaremos los siguientes componentes:

- ZConnection1;
- ZReadOnlyQuery1;
- Ztable1

Ahora en el evento OnCreate del DataModule1 lo siguiente (Debes colocar la BD y el Archivo sqlite3.dll en la misma carpeta del proyecto):
 


delphi
  1. USes ...Forms, Dialogs;
  2.  
  3. procedure TDataModule1.DataModuleCreate(Sender: TObject);
  4. begin
  5. ZConnection1.Database:= ExtractFilePath(Application.ExeName) + 'main.db';
  6. ZConnection1.LibraryLocation:= ExtractFilePath(Application.ExeName) + 'sqlite3.dll';
  7. ZConnection1.Protocol:= 'sqlite-3';
  8.  
  9. ZConnection1.Connected:=true;
  10. end;

En el Form1 colocaremos los siguientes componentes:

 

- 2 TEdits (edNombre, edEdad: ponemos por defecto 'Juan' y '12');

- 1 TButton;

 

En el Botón colocamos lo siguiente:


delphi
  1. Uses ...,Unit2; //Nombre del DataModule1 para hacer referencia a los componentes ZEOS
  2.  
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. begin
  5. //Estamos creando no leyendo, asi que solo lectura!!
  6. DataModule1.ZReadOnlyQuery1.Close; //Por si acaso
  7. DataModule1.ZReadOnlyQuery1.SQL.Text := 'CREATE TABLE IF NOT EXISTS main.personas(nombre TEXT,edad INT)';
  8. DataModule1.ZReadOnlyQuery1.ExecSQL;
  9.  
  10. DataModule1.ZTable1.TableName:= 'main.personas'; //Primero asignamos la tabla
  11. DataModule1.ZTable1.Open; //Luego abrimos la coneccion
  12. DataModule1.ZTable1.Insert;
  13. DataModule1.ZTable1.FieldByName('nombre').AsString:=edNombre.text;
  14. DataModule1.ZTable1.FieldByName('edad').AsInteger:=StrToInt(edEdad.text);
  15. DataModule1.ZTable1.Post; //Guardamos
  16.  
  17. //Cerramos la tabla
  18. DataModule1.ZTable1.close;
  19. end;

Verifica que registró los datos.

 

Nota:

 

Debes enlazar los compontes Zeos (ZReadOnlyQuery y ZTable) a Zconnection.

 

Saludos.


  • 0

#25 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 250 mensajes

Escrito 16 marzo 2016 - 03:36

Gracias Egostar por animarme a seguir adelante, desde luego si personas como tú otras tantas que apoyan al principante, y no lo dejan en el olvido siempre es un reto personal además de confiar en uno mismo que cualquier tropiezo, duda o consulta hay personas en este foro que puedan darte un empujón y seguir aprendiendo. Gracias amigo!

 

Voy a probar enecumene con tu código que desde luego es muy parecido al que expuse al principio, Hay algunas sentencias que aunque tiene comentarios no saco conclusiones y tengo duda al respecto ya que son nuevas para mí. A ver que obtengo.

 

Igualmente compararé con la "demo" que Delphius tiene en desarrollo para ver y diferenciar que nuevas sentencias hay, aparte de los comentarios que plasme en el mismo codigo.

 

Gracias y mil veces gracias!

 

un saludo


  • 0

#26 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.890 mensajes
  • LocationArgentina

Escrito 16 marzo 2016 - 05:00

Hoy estoy a media pila, y encima me acabo de sobre esguinzar de nuevo. :@  Me estaba recuperando de un esguince que sufrí hace mes y medio y hoy me acabo de volver a caer y se me ha vuelto a inflar el tobillo. Si, estaba consciente que mi pié todavía estaba en proceso de curado, pero al menos podía caminar sin la bota ortopédica y la inflamación ya practicamente se había ido. Y la molestia más que nada era por tener que caminar grandes distancias. Necesitaba ir a un traumatólogo y hacer fisioterapia pero plata no hay. Ahora con este nuevo accidente si o si voy a tener que hacerme ver por un especialista. La vez pasada consulté con un clínico que estaba de guardia en el Hospital.

Con la empastillada que me acabo de dar, me extraña que no esté viendo unicornios o elefantes rosas. :D

 

Si puedo continuar con la demo lo haré más tarde, durante la noche. Sino tendrá que ser mañana.

 

Veo que Fernando (enecumene) te ha estado dando más asistencia. Su prueba confirma mi teoría: si al momento de crear la base de datos le defines un schema (como el main) NECESARIAMENTE debes llamar a las tablas (y creería que a las vistas y triggers también) anteponiendo el schema. Es decir, que en tu TZTable debes ponerle como nombre de tabla main.personas.

Observa que en la consulta SQL que puse en mi demo y comenté en mi último post llamo a la tabla por "main"."personas". Por el código de muestra de enecumene aparentemente las comillas dobles no son extrictamente necesarias. Al menos al momento de asignarle tabla al TZTable, en una instrucción SQL quizá si requiera (tendría que probarlo)

 

Como tu no le pasas el main, tu TZTable no hace nada, y por tanto no verás ningún dato. Recuerda que para que un control db-ware funcione debe estar habilitado (Enable = true) esto también puede hacerte creer que no funcionada nada.

 

Estoy convencido que si cambias el personas por main.personas en la propiedad TableName del TZTable (creo que asi era la propiedad... no tengo Lazarus abierto ahora mismo) te va a empezar a funcionar.

 

Y no te dejes intimidar por la programación. No voy a mentirte y decirte que es fácil, pero no es imposible y vale la pena seguir intentando. Recuerda que tenemos toda una sección en el foro dedicada a tutoriales y manuales. Hay material de consulta y empezar a solidificar tus conocimientos. Y no temas preguntar que acá en el foro todos estamos para todos.

 

Saludos,


  • 0

#27 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 250 mensajes

Escrito 18 marzo 2016 - 12:21

:| Vaya que 'mala pata' lo tuyo Delphius, Debes tener más precauciones por ese esguince, esos "problemillas" suelen dar mucho dolores de cabeza, y más si lo dejamos o confiamos en que se van a solucionar con el tiempo sin actuaciones. Cuídate de ello, y dedícate todo el tiempo que puedas, te ahorras mucho de esto último si lo adelantas ahora. Espero y deseo que no vaya a más y te remita el daño. ya contarás... :)
 
Estoy intentado antes de usar el codigo que enecumene tiene implementado, cambiar el ZTable1 en tablename y poner: main.personas, pero no se porque leches ahora me indica:
 
SQL ERROR: SQL LOGIC ERROR OR MISSING DATABASE, impidiendo compilación completa. He empezado desde cero creando los componentes en el datamodule1 nuevamente, e insertando el codigo inicial que dispongo y me "salta" ese aviso!. Las dll están en system32, sysWOW y en carpeta proyecto... 8o|



si al momento de crear la base de datos le defines un schema (como el main) NECESARIAMENTE
debes llamar a las tablas (y creería que a las vistas y triggers también) anteponiendo el schema.
Es decir, que en tu TZTable debes ponerle como nombre de tabla main.personas.


 Entonces porque me funcionó sin definir un schema cuando lo implementé tal y como indica el tutorial usando el DBNavigator en vez de botones individuales como es mi caso ahora?


  • 0

#28 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.135 mensajes
  • LocationRepública Dominicana

Escrito 18 marzo 2016 - 01:21

Hola Dooper, lee detenidamente mi código y verás que que cargo la librería directamente desde la carpeta de la aplicación, y segundo debes tener creada la BD de datos sin la tabla de antemano, que es lo que indica el error que mencionas.

 

Saludos.


  • 0

#29 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 250 mensajes

Escrito 18 marzo 2016 - 01:34

Hola Dooper, lee detenidamente mi código y verás que que cargo la librería directamente desde la carpeta de la aplicación, y segundo debes tener creada la BD de datos sin la tabla de antemano, que es lo que indica el error que mencionas.

 

Saludos.

 

Hola enecumene, he visto que cargas la librería con una sentencia de codigo. En mi caso según el tutorial que ví, no lo hace por ninguna parte, lo indico en las propiedades del componente. Lo que aun no comprendo es como en tantas compilaciones anteriores no me había "saltado" el mensaje comentado, cuando estaba igual.

 

Las propiedades que he tocado de los componentes han sido: 


php
  1. Zconnection1.Protocol=SQLITE-3
  2.  
  3. Zconnection1.Database=F:\PROYECTO\gente.sqlite
  4.  
  5. Zquery1.Connection=Zconnection
  6.  
  7. ZTable1.Connection=Zconnection
  8.  
  9. DataSource.Dataset = Ztable1
  10.  
  11. Grid.DataSource=Datasource
  12.  
  13. Ztable1.Tablename=personas

Solo quería como ultima opción probar el cambiar en Ztable1.Tablename e indicarlo con "main.personas" a ver si era de eso, pero con este nuevo error que antes ni salía me lo impide, por lo tanto probaré con el código que implementas que está mejor definido y más completo sin duda alguna.


php
  1. ZConnection1.Database:= ExtractFilePath(Application.ExeName) + 'main.db';
  2. ZConnection1.LibraryLocation:= ExtractFilePath(Application.ExeName) + 'sqlite3.dll';

Estas dos instrucciones la última carga la librería que comentamos de la carpeta donde este el proyecto verdad? pero la segunda opción no consigo entender que realiza...

 

Porque usamos ZReadOnlyQuery1? y no ZQuery1? cuando usar una u otra?


  • 0

#30 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.135 mensajes
  • LocationRepública Dominicana

Escrito 18 marzo 2016 - 02:23

A ver, ¿.splite?, ¿esa extensión existe?, ¿has visto que utilizo el formato .db?, de todos modos te dejo los archivos de mi prueba:

 

https://drive.google...iew?usp=sharing

 

Saludos.


  • 0

#31 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 747 mensajes
  • LocationArgentina

Escrito 18 marzo 2016 - 03:29

A ver, ¿.splite?, ¿esa extensión existe?, ¿has visto que utilizo el formato .db?, de todos modos te dejo los archivos de mi prueba:

 

 

 

Se le puede poner la extension que se quiera

 

Entre los mas usados estan .sqlite, .sdb, .s3db, pero tranquilamente se puede poner lo que sea

 

Por ejemplo hay reproductores que le ponen .playlist, .bookmarks. .files, en cierto modo lo usan para indicar que hay adentro


  • 2

#32 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.500 mensajes
  • LocationMéxico

Escrito 18 marzo 2016 - 04:15

Se le puede poner la extension que se quiera

 

Entre los mas usados estan .sqlite, .sdb, .s3db, pero tranquilamente se puede poner lo que sea

 

Por ejemplo hay reproductores que le ponen .playlist, .bookmarks. .files, en cierto modo lo usan para indicar que hay adentro

 

Yo suelo asignarles la extensión db3. :)

 

Saludos.


  • 0

#33 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.890 mensajes
  • LocationArgentina

Escrito 18 marzo 2016 - 06:49

En un rato me pongo con esto y termino la demo.

Estoy a cuartos de pila.

Hasta el momento no me he topado con ningún problema mientras estuve haciendo mis pruebas.

Ni bien termine, subo el ejemplo.

 

Saludos,


  • 0

#34 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.890 mensajes
  • LocationArgentina

Escrito 18 marzo 2016 - 08:34

Bueno, ya terminé la demo, es algo básica pero te servirá para que entiendas como se procede con la conexión, creación e inserción. Actualizaciones o modificaciones y eliminaciones se hacen por analogía de conceptos.

 

El demo no es a prueba de fallos, sobre todo si uno es super juguetón. Al estar todos los botones habilitados cualquier intento de insertar sin haber creado la base de datos o siquiera haberse conectados obviamente dará error. Pero la idea es justamente ilustrar los conceptos y no hacer una aplicación super robusta.

 

En el código observarás que para la creación de la base de datos se utilizó la siguiente instrucción:


sql
  1. CREATE TABLE IF NOT EXISTS "main"."personas" ("nombre" VARCHAR(30), "edad" INTEGER)

Al definir main como schema estás obligado a usar main.personas para cualquier operación sobre la tabla. Por tanto esto puede dar motivos de error si no prestas atención a este detalle.

No me puse a estudiar que diferencia hay entre definir o no un schema. No me puse a leer la documentación de SQLite, simplemente me acoto a hacer esta prueba.

 

El demo ofrece dos posibilidades de trabajo: con el query y/o con el table. ¿Porqué? Porque soy un tipo divertido y me gusta exprimir cerebros para que vayan aprendiendo y familiarizándose con los conceptos de ambos. Por regla general los tables no son óptimos, y necesitan leer y tener acceso a todo los registros. Esto puede ser muy lento cuando la tabla tiene muchísimos registros. Por su parte los querys dan más versatilidad y permiten delegar el poder en los servidores. El ¡SQL es mucho más ventajoso!

 

Para avanzar, deberás familiarizarte tarde o temprano con SQL y por tanto con los Querys.

El Grid estará inactivo la mayor parte del tiempo. Es más, sólo se habilita (y enlaza) al dataset con el que elijas conectarlo sólo cuando presionas en los botones "Mostrar Grid".

Luego hay un botón para cerrar el Grid.

 

Puedes insertar elementos con cualquier dataset, el código es simple. Mientras se usa el query, el table estará inactivo. Y a la inversa cuando usas el Table. Esto es así para evitar justamente que ambos datasets por accidente se intenten vincular o enlazar hacia el mismo (y para este caso, único) datasource.

 

Observarás que hago uso de transacciones. Como te lo he mencionado: esto es un modo muy seguro de trabajar... incluso en un ambiente mono-usuario no está desestimado su uso. Esto permite que cuando uno tiene que hacer muchas operaciones ABM para un proceso determinado, se realicen todas o ninguna. Imagina que por ejemplo que estás creando un sistema ERP. Un proceso como "vender un artículo" no termina con el insertar en la tabla de ventas, y en restar en la tabla artículos. Se disparan más instrucciones relacionadas como ser añadir el asiento contable  que refleje la venta, se debe disparar el proceso para control de reposición, y otros más. Sin el poder de una transacción, si alguna de esas operaciones falla la base de datos estará en un estado inconsistente, habrá información incompleta.

Al encapsular todo esto en una transacción te aseguras que se haga todo, y en caso de error que se descarten los cambios. De esta forma la base de datos estará más segura.

 

También para apoyar este concepto de las transacciones hago uso de excepciones. Verás mucho algo como esto:


delphi
  1. try
  2. // hacer algo
  3. except on E: Exception do
  4. begin
  5. ShowMessage(E.Message);
  6. end;
  7. end;

¿Que significa todo eso?

Básicamente lo que dice es "Intenta hacer todo el algo, si algo falla (Exception es el tipo de error más general. Lo ideal es capturar errores específicos) muestra el mensaje de la excepción"

 

Combinando transacciones y excepciones la cosa es "Inicio transacción. Intenta hacer todo esto, si algo falla dime el error y cancela todo".

 

En el .zip encontrarás la base de datos de prueba que yo definí (dbclientes.sqlite) , y los archivos que necesita SQLite: el .dll y el .def. Para poder ejecutar el demo deberás cambiar la ruta de conexión y de la dll del componente TZConnection. Enecumente te aportó una forma de hacer esto de forma más limpia que es la de leer el directorio donde está el ejecutable y armar la ruta hacia dichos archivos. Por ejemplo se puede aprovechar el OnCreate() del Form para hacer esto.

 

Notarás que los datasets están cerrados, y que el TZConnection también lo está. No es bueno mantenerlos en Connected en true. Es preferible hacerlo en tiempo de ejecución. Tanto el TZQuery como el TZTable están vinculados al TZConnection.

 

En TZConnection se ha establecido en Protocol sqlite-3, el TZQuery se mantiene como está por defecto (obvio, con su conexión) y en el TZTable en TableName se asignó main.personas.

 

Prueba con la base de datos que hice. Inserta, y muestra con cualquiera de los datasets. Luego te invito a que la borres, y crees una de nuevo.

Advertencia: Este demo ha sido compilado en 64bits. Si efectivamente tienes este bitness, como asumo que es el correcto según nos indicas, no debiera de haber problema. Ahora si tu equipo es de 32bits deberás reemplazar los archivos de SQLite por su versión 32bits y también deberás recompilarlo con Lazarus o bien con CodeTyphon en 32bits, sugiero que también elimines la carpeta lib. Esto es muy importante. No hay que mezclar 32bits con 64bits. Es motivo de problemas. Antes de nada, haz una copia de respaldo por las dudas.

 

Adjunto el zip. Estuve intentando ver la posibilidad de ponerlo en forma pública en mi cuenta en Hubic (un servicio alternativo a Dropbox) pero aparentemente no tiene un especie de enlace como para copiar y distribuir. La opción de "publicar" es a traves de e-mail o por alguna red social.

 

Saludos,

Archivos adjuntos


  • 1

#35 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 250 mensajes

Escrito 19 marzo 2016 - 05:01

Impresionante Delphius como siempre, acabo de descargar la "demo" en cuanto tenga un hueco libre, la veo ansiosamente. No sin antes terminar el codigo de enecumene implementó que lo tengo casi todo insertado a ver que hace, espero no "salte" por los aire con alguna cosa que haya cambio yo de antemano.

 

Nunca llegué a pensar que mis comienzos en trabajar con una simple bbd.dd en Lazarus me fueran a dar tantos dolores de cabeza, y más cuando en mi anterior equipo con XP, usé el mismo "tutorial" y funcionó de la misma forma que ahora está en mi nuevo equipo (componentes, sentencias, etc....).

 

Iré viendo que hace cada sentencia de las que haya en la "demo", a ver si puedo entender su finalidad.

 

Como buen "profesor" explicando los conceptos, creo que uno de mis problemas, es que confundo Ztable y Zquery, pienso que sobre lo que hay que trabajar es con ZTable ya que es la tabla la que tiene los registros insertados, pero claro puede ser que

tengamos muchas tablas y no el Zquery, y este ultimo para mí es un consulta en sí que simplemente lee/consulta datos determinados de esa Ztable. Luego está la conexion que hay entre ambos componentes que no relaciono cuales y porque

están interconectados entre sí... He leido por ahí muchos tutos sobre este tema, pero nada me queda claro, viendo lo

retorcidos que algunos tutoriales lo exponen, seguiré leyendo aparte de vuestros aportes para ir comprendiendo más el tema

de las bbdd y su implementación en la programación Lazarus.

 

 

Gracias y os informo de los avances.

 

saludos


  • 0

#36 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.890 mensajes
  • LocationArgentina

Escrito 19 marzo 2016 - 08:01

Hola Dooper,

Tanto las Tables como los Query se pueden emplear para lo mismo. Ambos no son más que una abstracción de un conjunto de datos devuelto por el motor de base de datos. Con ambos se puede insertar, modificar, eliminar. La diferencia está en que los Tables trabajan sobre una unica tabla (y en ciertos casos también pueden ser una vista) definida. Cuando uno hace un .Open sobre un Table el componente lo que hace es traer TODO el conjunto de datos (los registros) que tiene dicha tabla (*), lo cual puede ser una desventaja en un ambiente Cliente/Servidor y/o cuando hay muchos registros. Sus operaciones se realizan "localmente" en memoria y luego se da aviso al servidor.

Los Querys en cambio están diseñados para aprovechar el poder del motor y el SQL y también permiten ejecutar algunos scripts. Son más versátiles, con ello en lugar de hacer un SELECT * sobre una única tabla se puede tener una consulta que nos devuelva un conjunto de datos formado por campos de varias. En escencia un Table cuando haces un .Open la instrucción se traduce en un SELECT * hacia el motor, y por lo general hacer un "select all" no es una implementación eficiente. Con el Query podemos desde elegir un conjunto de datos específicos hasta también indicar que campos y no necesariamente todos.

 

Ambos tienen sus utilidades.

Se puede estar trabajando con ambos, y hasta sobre la misma tabla "al mismo tiempo". Pero de hacerlo se debe tener mucho control sobre como se van a ir procediendo a hacer las operaciones. El Query no es para leer los datos insertados de un Table, no necesariamente. Ahí si tienes un error de concepto.

 

(*) Bueno, en realidad algunos tables y querys permiten configurarse para traer "grupos" de registros y no todo el conjunto y uno puede indicar de a cuantos. Por ejemplo, traer en grupos de 100 a 100. Y el componente automáticamente cuando uno se mueve por los registros determina si tiene que cargar un nuevo grupo. Pero por defecto, esto está en 0. Es decir: traer todo.

 

Yo te recomiendo que leas el libro La Cara Oculta de Delphi 4 y no esos tipos de tutoriales "aprende en 21 días" que pupulan en sitios como la web del programador. Te aportará una riqueza conceptual y disipará muchas dudas. Es quizá el material de lectura obligada más difundido. Si, es cierto dice Delphi en el título. Pero lo que leas es igualmente aplicable a Lazarus, después de todo los conceptos se basan en Object Pascal y si algo hace bien el equipo de Lazarus es mantener buena compatbilidad hacia Delphi. Si, tienen sus diferencias pero más que nada aplica a nombres de algunas propiedades y algún que otro componente y/o funcionamiento interno. Pero en escencia todo lo que leas es aplicable. Como su autor ha decidido liberar los derechos de distribución lo podrás descargar desde diferentes sitios. Lamentablemente nuestra Sección de Descargas tiene algunas dificultades, por lo que te recomiendo que lo busques.

El buen Caral hizo unos cuantos tutoriales que encontrarás en el foro. Puedes extrapolar todo lo que leas en Lazarus. Si aún no lo leíste, hazlo. No tienen desperdicio.

Y también hay que perder el miedo al inglés. No te digo que te lo sepas mejor que Shakespeare, pero si... algo es conveniente saberlo. En ocasiones habrá que ir a los propios foros de Lazarus, CodeTyphon y/o de las empresas y terceros que realizan los componentes.

 

Saludos,


  • 0

#37 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 250 mensajes

Escrito 19 marzo 2016 - 12:21

Tomo nota de tus sabios consejos delphius. Dispongo de un cuadernillo donde transcribo todo los conceptos, errores y consejos que me habeis aportado durante todo este tiempo, se agradece ir ampliando hojas al mismo.

 

Como dije, estoy a punto de terminar de pasar elcodigo que enecumene de indicó y ver si funcionaba, aparte de analizar a continuación la "demo" de Delphius paso a paso, pero en la sentencia


php
  1. ExtractFilePath(Application.ExeName) + 'main.db';

me indica que identificador no encontrado "Application". No se si hay este instrucción no es reconocida por Lazarus, pero me parece raro, ya que enecumene ha probado y funcionaba en su "demo". Hay otra instrucción debajo que tiene ese misma palabra reservada. He puesto la unidad en USES SysUtils, por si era de ahí, pero nada...concepto nuevo, aprendizaje nuevo!

 

 

un saludo


  • 0

#38 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.135 mensajes
  • LocationRepública Dominicana

Escrito 19 marzo 2016 - 01:26

Debes incluir la Unidad Forms en el Uses, como lo indiqué en mi ejemplo:

 


delphi
  1. Uses ...Forms, Dialogs;

 

Saludos.


  • 0

#39 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 250 mensajes

Escrito 19 marzo 2016 - 02:30

Gracias enecumene,.... los árboles me están impidiendo ver el bosque, a estas alturas del problema.

 

Veamos, he plasmado el codigo que me probaste enecumene, y me saltaba siempre un error SQL ERROR. SQL LOGIC ERROR OR MISSING DATABASE. Insistiendo porque hice un leve cambio en tu codigo encuanto a la creación de los campos de la tabla.

 

Tú indicabas así.


php
  1. DataModule1.ZReadOnlyQuery1.SQL.Text := 'CREATE TABLE IF NOT EXISTS main.personas(nombre TEXT,edad INT)';

pero cambié la instrucción a esta:


php
  1. DataModule1.ZReadOnlyQuery1.SQL.Text := 'CREATE TABLE IF NOT EXISTS main.personas(nombre VARCHAR(10),edad INTEGER)';

y así me probocaba ese error que comento. Siempre he visto que la declaración de los campos si son texto es VARCHAR, y numeros INTEGER, pero no había visto nunca la declaracion con TEXT e INT.

 

Ahora  crea la BB.DD main.db, edito el fichero y veo que ha insertado los campos que le he indicado en fieldByName:='Juan'; fieldByName:=12; pero aparte de ello, me carga una serie de caracteres


php
  1. SQLite format 3 @ -ñ¹
  2. Ÿ Ÿ _%%tablepersonaspersonasCREATE TABLE "personas"(nombre TEXT, edad INT)
  3. é é )Juan12

que no se si es normal.

 

Claro está esa información es laque se graba, pero en el DBGRid ahora mi intención es que aparezcan los registros en el, supongo que con hacer lo mismo pero con ZTable1.Edit, podrá cargarlo.


  • 0

#40 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.135 mensajes
  • LocationRepública Dominicana

Escrito 19 marzo 2016 - 02:33

SQLite no reconoce VARCHAR, sólo TEXT, te dejo la documentación de SQLite


  • 1