In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Unir databases con SqliteDataSource

Foro público de Xailer en español
Responder
Alfredo Sanz
Mensajes: 15
Registrado: Sab Nov 26, 2011 5:20 pm

Unir databases con SqliteDataSource

Mensaje por Alfredo Sanz »

Hola,
Alguien sabe si se pueden unir databases con el SqliteDatasource
http://www.sqlite.org/lang_attach.html
Y si así­ no se puede, ¿Alguna forma de hacerlo?
1 Saludico,
Fredy
Avatar de Usuario
Carlos Ortiz
Mensajes: 873
Registrado: Mié Jul 01, 2009 5:44 pm
Ubicación: Argentina - Córdoba
Contactar:

Unir databases con SqliteDataSource

Mensaje por Carlos Ortiz »

Sqlite no soporta el comando UNION para unir tablas?
El 05/03/2013 20:06, Alfredo Sanz escribió:
> Hola,
> Alguien sabe si se pueden unir databases con el
> SqliteDatasource
>
> http://www.sqlite.org/lang_attach.html
>
> Y si así­ no se puede, ¿Alguna forma de hacerlo?
>
> 1 Saludico,
> Fredy
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9441
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Unir databases con SqliteDataSource

Mensaje por ignacio »

Alfredo Sanz escribió el mié, 06 marzo 2013 00:06Hola,
Alguien sabe si se pueden unir databases con el SqliteDatasource
http://www.sqlite.org/lang_attach.html
Y si así­ no se puede, ¿Alguna forma de hacerlo?
1 Saludico,
Fredy
Mira el comando ATTACH DATABASE. La única limitación es que si utilizas encriptación ambas bases de datos han de estar encriptadas con la misma contraseña.
Saludos
Ejemplo de traspaso de tabla entre dos BD:
WITH OBJECT oDataSource
TRY
:Execute( "ATTACH DATABASE 'c:....???.db' AS Source" )
:BeginTrans()
:Execute( "DELETE FROM Tabla" )
:Execute( "INSERT INTO Tabla (campos,...) SELECT (campos, ...) FROM Source.Tabla )
:CommitTrans()
:Execute( "DETACH DATABASE Source" )
CATCH
:RollBackTrans()
Msginfo( "Error en grabación de los datos" )
END
END WITH
Ignacio Ortiz de Zúñiga
[OZ Software]
https://www.ozs.es
--
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Alfredo Sanz
Mensajes: 15
Registrado: Sab Nov 26, 2011 5:20 pm

Unir databases con SqliteDataSource

Mensaje por Alfredo Sanz »

Gracias, justo lo que buscaba.
Por cierto, sabes si hay alguna forma de conocer en sqlite si una base de datos o una tabla se encuentra bloqueada?
El problema que tengo es que si intento hacer un Execute Insert, Update, etc y hay una transacción en curso no me entero hasta que sqlite me devuelve un error 5
1 Saludico,
Fredy
Alfredo Sanz
Mensajes: 15
Registrado: Sab Nov 26, 2011 5:20 pm

Unir databases con SqliteDataSource

Mensaje por Alfredo Sanz »

Hola Carlos.
Sí­ que soporta Union sobre Tablas.
Yo preguntaba más o menos lo mismo pero sobre Datablases
1 Saludico,
Fredy
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9441
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Unir databases con SqliteDataSource

Mensaje por ignacio »

Hola Fredy,
Creo que SQLite bloquea la BD completamente en cada operación de escritura, por eso es tan importante usar transacciones, de esta forma se le indica a Sqlite cuando empieza y termina la transacción.
Yo personalmente pongo la propiedad lAllowProcessMessages a falso. Es posible que también te sea de ayuda.
Y por último, soy partidario de utilizar TMemDatasets cuando no voy a editar los SELECTS que haga ya que entonces los filtros y ordenaciones se resuelven sin necesisdad de usar el motor de SQLITE. Ver método TDataSource:QueryMemDataset()
Un saludo
Ignacio Ortiz de Zúñiga
[OZ Software]
https://www.ozs.es
--
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Alfredo Sanz
Mensajes: 15
Registrado: Sab Nov 26, 2011 5:20 pm

Unir databases con SqliteDataSource

Mensaje por Alfredo Sanz »

El problema es ese, que bloquea la base de datos entera y no sólo las tablas utilizadas en la transacción.
En un entorno multiusuario, si otro usuario inicia una transacción y yo intento iniciar otra antes de que la del usuario 1 finalice, sqlite genera un error 5 (Database is locked).
El problema que me genera esto, es que cuanto más larga sea la transacción más fácil es que otro usuario tenga problemas. Imagí­nate una regeneración de almacenes que dure 3 minutos. Si no uso transacciones, en lugar de 3 minutos igual son 30. Si uso transacciones, cualquier usuario que intente grabar un dato durante los 3 minutos del proceso recibirá como respuesta un error de sqllite y posiblemente pierda los datos introducidos.
Por eso me gustarí­a conocer de antemano si la base de datos está bloqueada y esperar a que la base de datos esté desbloqueada en lugar de que genere el error.
En la prehistoria, con dbfs tení­amos el FLock(), que es algo parecido.
He probado con nTimeOut, pero creo que sqlite no lo utiliza.
Según he visto en http://www.sqlite.org/tempfiles.html
creo que puedo solucionarlo jugando con el fichero -journal de la database , pero serí­a mucho más fácil si ya existe algo para hacerlo.
1 Saludico,
Fredy
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5718
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Unir databases con SqliteDataSource

Mensaje por jfgimenez »

Fredy,
> El problema es ese, que bloquea la base de datos.
>
> En un entorno multiusuario, si otro usuario inicia una
> transacción y yo intento iniciar otra antes de que la del
> usuario 1 finalice, sqlite genera un error 5 (Database is
> locked).
>
> El problema que me genera esto, es que cuanto más larga sea
> la transacción más fácil es que otro usuario tenga
> problemas. Imagí­nate una regeneración de almacenes que
> dure 3 minutos. Si no uso transacciones, en lugar de 3
> minutos igual son 30. Si uso transacciones, cualquier
> usuario que intente grabar un dato durante los 3 minutos del
> proceso recibirá como respuesta un error de sqllite y
> posiblemente pierda los datos introducidos.
Lo ideal con SQLite es que las transacciones sean muy rápidas, nunca más
de unos pocos (muy pocos) segundos. Si hay procesos que requieren
transacciones largas, y en un entorno multiusuario, entonces lo más
indicado es cambiar a otra BD.
La BD más parecida a SQLite, en cuanto a sintaxis, es MySQL. Yo tengo
aplicaciones que soportan ambos motores, y que se cambia de uno a otro
desde una opción de configuración. Todo el programa, excepto la parte de
abrir y crear las BB.DD., es común a ambos motores, es decir, que no he
tenido que cambiar ni una lí­nea de código para usar uno u otro. Y tengo
unas cuantas sentencias relativamente complejas. Tan sólo hay una
pequeña diferencia que encontré entre ambos, pero no es muy habitual
tropezarte con eso.
Ahora bien, MySQL es de pago. Pero afortunadamente, ahora tenemos una
alternativa: MariaDB ;-)
> Por eso me gustarí­a conocer de antemano si la base de datos
> está bloqueada y esperar a que la base de datos esté
> desbloqueada en lugar de que genere el error.
>
> En la prehistoria, con dbfs :) tení­amos el FLock(), que es
> algo parecido.
El eterno dilema de los "bloqueos pesimistas" frente a los "bloqueos
optimistas"...
> He probado con nTimeOut, pero creo que sqlite no lo
> utiliza.
>
> Según he visto en http://www.sqlite.org/tempfiles.html
> creo que puedo solucionarlo jugando con el fichero -journal
> de la database , pero serí­a mucho más fácil si ya existe
> algo para hacerlo.
Hasta donde yo sé, los journals son otra cosa. Los crea la propia BD
durante una transacción, y sólo sirven para hacer un rollback automático
cuando se abre la BD después de un corte de luz o algún fallo similar.
Pero dudo mucho que puedas manipularlos o usarlos directamente para
ningún otro fin.
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
Alfredo Sanz
Mensajes: 15
Registrado: Sab Nov 26, 2011 5:20 pm

Unir databases con SqliteDataSource

Mensaje por Alfredo Sanz »

Qué tal José,
> Lo ideal con SQLite es que las transacciones sean muy rápidas, nunca más
> de unos pocos (muy pocos) segundos. Si hay procesos que requieren
> transacciones largas, y en un entorno multiusuario, entonces lo más
> indicado es cambiar a otra BD.
Lo chulo de sqlite es que tiene cosas muy muy buenas y cosas muy muy malas, pero para ese estamos nosotros.
> La BD más parecida a SQLite, en cuanto a sintaxis, es MySQL
Lo malo es que todo lo que ganas en compatibilidad SQLite-MySQL lo pierdes en potencia de MySQL.
> Ahora bien, MySQL es de pago. Pero afortunadamente, ahora tenemos una
> alternativa: MariaDB
Sí­! Indudablemente se nos ha aparecido la Virgen ...MariaDb
> El eterno dilema de los "bloqueos pesimistas" frente a los "bloqueos
> optimistas"...
Sí­, pero es que el tí­o que inventó Sqlite es el rey de los pesimistas. Mira tú que bloquear a nivel de base de datos!!
> Hasta donde yo sé, los journals son otra cosa. Los crea la propia BD
> durante una transacción, y sólo sirven para hacer un rollback automático
> cuando se abre la BD después de un corte de luz o algún fallo similar.
> Pero dudo mucho que puedas manipularlos o usarlos directamente para
> ningún otro fin.
Realmente no lo manipulo. Sólo compruebo 2 cosas:
- Existencia:
Si no existe, está claro que nadie tiene una transacción abierta
Si existe
- Apertura en exclusivo
Si lo puedo abrir el fichero en modo exclusivo, es que el programa a petado y se ha quedado el fichero perdido
Si no lo puedo abrir es que alguien tiene una transacción en curso y me toca esperar.
1 Saludico,
Fredy
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9441
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Unir databases con SqliteDataSource

Mensaje por ignacio »

Hola,
Se me ocurre que un bloque TRY..CATCH dentro de un bucle con salida cuando transcurra cierto tiempo serí­a suficiente. No?
Prueba también con BEGIN EXCLUSIVE TRANSACTION
Saludos
Ignacio Ortiz de Zúñiga
[OZ Software]
https://www.ozs.es
--
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5718
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Unir databases con SqliteDataSource

Mensaje por jfgimenez »

Fredy,
> Lo chulo de sqlite es que tiene cosas muy muy buenas y cosas
> muy muy malas, pero para ese estamos nosotros.
Pues sí­, la verdad. Yo soy de los que me gusta muchí­simo SQLite, aunque
es cierto que hay que lidiar con algunas cosas muy suyas... pero claro,
se entiende desde el punto de vista de que es un motor empotrado y
local, ¡ahí­ es ná!
> Lo malo es que todo lo que ganas en compatibilidad
> SQLite-MySQL lo pierdes en potencia de MySQL.
Sí­, puede haber ciertas cosas que tiene MySQL y que no tiene SQLite,
pero si lo que tienes es una aplicación diseñada con SQLite, al añadir
soporte para MySQL no vas a echar nada en falta.
> Sí­, pero es que el tí­o que inventó Sqlite es el rey de
> los pesimistas. Mira tú que bloquear a nivel de base de
> datos!!
Bueno, al revés... es el rey de los optimistas. Vamos, que bloquea toda
la BD porque... "si total, no van a coincidir nunca" ;-)
> Realmente no lo manipulo. Sólo compruebo 2 cosas:
> - Existencia:
> Si no existe, está claro que nadie tiene una
> transacción abierta
> Si existe
> - Apertura en exclusivo
> Si lo puedo abrir el fichero en modo exclusivo,
> es que el programa a petado y se ha quedado el fichero
> perdido
> Si no lo puedo abrir es que alguien tiene una
> transacción en curso y me toca esperar.
No te fies. Yo no los he investigado a fondo, pero estoy convencido de
que el fichero journal lo crea con la primera transacción que hagas,
pero seguramente no lo borra, sino que solamente lo trunca, para no
tener que crearlo y borrarlo cada vez.
No obstante, para el problema que tienes, se me ocurre que podrí­as
forzarlo a iniciar una transacción antes de emprezar con la grabación de
datos, y si la transacción falla, entonces avisas al usuario. Podrí­as
hacerlo como una función del estilo de RLock(). P.ej. (y simplificando
mucho):
FUNCTION DBLock( oDB )
LOCAL lOk := .T.
TRY
oDB:BeginTrans()
oDB:Execute( "Update...." ) // Aqui pones cualquier cosa que
fuerce una grabacion para que se bloquee la DB
CATCH
lOk := .F.
END
RETURN lOk
y puedes llamar a esta función al estilo de como lo hací­as con los DBF.
Si retorna .F. es que no ha podido bloquear, y si retorna .T. es que la
BD ya la ha bloqueado e iniciado la transacción.
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
Avatar de Usuario
Carlos Ortiz
Mensajes: 873
Registrado: Mié Jul 01, 2009 5:44 pm
Ubicación: Argentina - Córdoba
Contactar:

Unir databases con SqliteDataSource

Mensaje por Carlos Ortiz »

Perdón vi tablas en lugar de databases.
Serí­a indicado dormir cuando es tarde digo por la hora en que conteste
tu post inicial, saludo.
Responder