Spanish [SOLUCIONADO] Error en BD SQL al crear tabla

TheFalcon

Active Member
Licensed User
Longtime User
Buenas, verán estoy haciendo una actualización para mi aplicación y va a llevar nuevas columnas y tablas, el problema lo tengo cuando desde código creo una tabla , en la aplicación sigue funcionando todo pero cuando voy a abrir la tabla SQL con el programa de PC que uso para verificar etc, me dice que el formato es invalido y no me deja abrirla para trabajar en el PC con ella.
Alguien sabe el por que? , el programa que uso es "DBBrowser for SQLITE"

E probado hasta con una consulta simple y directa para probar y nada, como cree tabla se casca , pero si creo columnas en las tablas no pasa nada. Estos tres modos e usado, el ultimo sacado del mismo foro.

B4X:
SQL1.ExecNonQuery("CREATE TABLE tab1 (sum NUMBER, id NUMBER)")

B4X:
SQL1.ExecNonQuery("CREATE TABLE Opciones (SaveSD TEXT)")

B4X:
Dim cursor2 As Cursor
    Dim i As Int
    Dim ssql As String
    Dim trobat As Boolean
    trobat=False
    cursor2 = SQL1.ExecQuery("SELECT name FROM sqlite_master WHERE Type='table'")
    For i = 0 To cursor2.RowCount - 1
        cursor2.Position=i
        If cursor2.GetString("name")="Opciones" Then trobat=True
    Next
    If trobat=False Then
        ssql=    "CREATE TABLE Opciones (SaveSD TEXT)"
        SQL1.ExecNonQuery(ssql)
        Msgbox("La base de datos se ha creado","Atención")
    End If
 

TheFalcon

Active Member
Licensed User
Longtime User
Planteare mi duda de otro modo :).
Como añadís vosotros una tabla nueva a una base de datos en SQL. nombre.sql , y con que programa comprobáis que se ha añadido sin problemas.

Un Saludo
 

vbmundo

Well-Known Member
Licensed User
Amigo

El problema es que no puedes crear una tabla vacia... al menos deberia tener 1 campo dentro...

cuando digo NO VACIA, no me refiero a incluirle datos... me refiero a que al menos debes crearle un campo, el cual luego podrás borrar si adicionas otros... al menos 1 campo tiene que quedar.

Por eso tu mismo te has respondido..
pero si creo columnas en las tablas no pasa nada

Saludos
 

TheFalcon

Active Member
Licensed User
Longtime User
El problema es que no puedes crear una tabla vacia... al menos deberia tener 1 campo dentro...

cuando digo NO VACIA, no me refiero a incluirle datos... me refiero a que al menos debes crearle un campo, el cual luego podrás borrar si adicionas otros... al menos 1 campo tiene que quedar.
Si pongo un campo, de echo si en el Programa con el que trabajo las bases de datos "DB browser for SQL lite " Ejecuto en las secuencias SQL
B4X:
CREATE TABLE Opciones (SaveSD TEXT)

me lo añade perfecto, el problema es cuando en la aplicación pongo
B4X:
SQL1.ExecNonQuery("CREATE TABLE Opciones (SaveSD TEXT)")
al coger la base de datos y abrirla para ver si se a creado bien me dice que el formato no se puede reconocer. Que lo mismo lo añade sin problemas pero no tengo como verificarlo, y después de eso tampoco puedo trabajar con la base de datos desde windows.


Buenas TheFalcon, podrías poner también la cadena de conexión?


B4X:
If File.Exists(File.DirDefaultExternal,"cetreros.sql") = False Then
        File.Copy(File.DirAssets,"cetreros.sql",File.DirDefaultExternal,"cetreros.sql")
    End If
   
    If SQL1.IsInitialized = False Then
        SQL1.Initialize(File.DirDefaultExternal, "cetreros.sql", False)
    End If
   
   
    DBload



B4X:
Sub DBload
ListView1.Clear'need to clear the list
cursor1 = SQL1.ExecQuery("SELECT * FROM Fichas")
For i = 0 To cursor1.RowCount - 1
cursor1.Position = i

ListView1.AddSingleLine(cursor1.GetString("Nombre"))
ListView1.SingleLineLayout.ItemHeight = 40dip
ListView1.SingleLineLayout.Label.TextSize = 20
ListView1.SingleLineLayout.Label.TextColor = Colors.Black
ListView1.SingleLineLayout.Label.Color = Colors.Transparent

Next
End Sub
 

dar2o3

Active Member
Licensed User
Longtime User
Bueno, acabo de probar la siguiente función y "funciona" correctamente.
Tengo la función en un módulo que lo llamo soporte, tu ponla donde quieras.

Me he descargado el mismo programa que usas tu para comprobar la bd en el pc y lo abre sin problemas.

B4X:
Sub creatabla(nombretabla As String, campo As String, tipo As String) As Boolean
    Dim sql3 As SQL
    If sql3.IsInitialized=False Then
        sql3.Initialize(File.DirRootExternal,"/tu_path/tu_bd.bd",True)
    End If
    Try
        sql3.ExecNonQuery($"CREATE TABLE ${nombretabla} (${campo.ToUpperCase} ${tipo.ToUpperCase} )"$)
        Return True
    Catch
        Return False
        Log(LastException)
    End Try



    sql3.Close
End Sub

Yo lo llamo de la siguiente manera

B4X:
If soporte.creatabla("pruebas","pp","text")=True Then
            Msgbox("Tabla creada de forma correcta","Victoria!!!")
        Else
            Msgbox("Error al intentar crear la tabla","Cagada")
    End If


upload_2016-8-14_19-8-53.png
 
Last edited:

TheFalcon

Active Member
Licensed User
Longtime User
La voy a probar ahora mismo, solo comentar iba a subir la BD como me comento Josnav , cogí una vacía que esta bien, y añadí la tabla y no se me corrompió, es decir solo se me corrompe cuando añado la tabla en una base de datos que ya tiene datos dentro ..... por si vale de orientación, voy a probar lo que me dices ahora mismo
 

dar2o3

Active Member
Licensed User
Longtime User
Yo lo he probado con una bd que ya contenía datos, como puedes ver en las imágenes (he borrado los datos en la imagen)
 
Last edited:

dar2o3

Active Member
Licensed User
Longtime User
Asegúrate de no tener ninguna otra conexión (sql) abierta a esa bd en ese momento, sqlite no maneja demasiado bien las conexiones concurrentes (aunque hay técnicas para poder hacerlo)
 

TheFalcon

Active Member
Licensed User
Longtime User
lo he probado como tu me has puesto y me dice lo mismo creo que sera por que por algún lado mi base de datos esta cogida al crear la tabla y se corrompe, por que si añado en una tabla vacía lo hace, lo único que cambie de tu código fue .


B4X:
sql3.Initialize(File.DirRootExternal,"/tu_path/tu_bd.bd",True)
Por
B4X:
 sql3.Initialize(File.DirDefaultExternal, "cetreros.sql",True)
 

dar2o3

Active Member
Licensed User
Longtime User
Asegúrate de hacelo en el main, cuando se ejecuta el programa y no tengas ningún otro "controlador" sql abierto a ver si es ese el problema, ya me pica la curiosidad a mi también.
la versión de sql que tengo es la 1.30 (por si acaso lo digo)
 

TheFalcon

Active Member
Licensed User
Longtime User
e probado a quitar la anterior secuencia SQL del Main para ver si no crea conflicto pero nada, yo tengo en el Main en Activity_create

B4X:
Sub Activity_Create(FirstTime As Boolean)

Activity.LoadLayout("principal")
Activity.Title = "titulo"



If File.Exists(File.DirDefaultExternal,"cetreros.sql") = False Then
        File.Copy(File.DirAssets,"cetreros.sql",File.DirDefaultExternal,"cetreros.sql")
    End If
   
    If SQL1.IsInitialized = False Then
        SQL1.Initialize(File.DirDefaultExternal, "cetreros.sql", False)
    End If

    DBload ' aquí llamo la funcion SQL para cargar los datos.

End Sub

y la funcion de cargar es:

B4X:
Sub DBload
ListView1.Clear'need to clear the list
cursor1 = SQL1.ExecQuery("SELECT * FROM Fichas")
For i = 0 To cursor1.RowCount - 1
cursor1.Position = i

ListView1.AddSingleLine(cursor1.GetString("Nombre"))
ListView1.SingleLineLayout.ItemHeight = 40dip
ListView1.SingleLineLayout.Label.TextSize = 20
ListView1.SingleLineLayout.Label.TextColor = Colors.Black
ListView1.SingleLineLayout.Label.Color = Colors.Transparent

Next
End Sub

es lo único que tengo SQL, las demás funciones SQL son al pulsar botones como crear nueva ficha etc.

Pero incluso des-habilitando esos 2 códigos me sigue dando error cuando pongo que me creeen activity create o incluso en un botón, la tabla.
Lo que me tiene mosca es que añadiendo columnas a tablas ya existentes no tengo problema

Aquí subo la base de datos ya corrupta después de añadir la tabla, le e puesto extensión txt por que extensión sql no me dejaba subirla , hay que renombrarlo.
 

Attachments

  • bbdd.txt
    18 KB · Views: 284

dar2o3

Active Member
Licensed User
Longtime User
Te falta en la función DBload

B4X:
cursor1.close


después del bucle para cerrar el cursor.
 

TheFalcon

Active Member
Licensed User
Longtime User
Igual :(, e estado probando toda la mañana y nada, también tengo SQL 1,30, esta noche seguiré probando mas descansado haber si doy el por que jeje
 

dar2o3

Active Member
Licensed User
Longtime User
Una cosa, Espero que no te siente mal, es una crítica constructiva ;), por lo que veo en el pedazo de código que has puesto arriba, declaras la variable cursor1 (no se si a nivel global) en algún sitio, esto me parece que es una mala práctica, precisamente por lo que te está pasando, al final acabas usándola e tantos sitios que no conoces el estado en el que se encuentra el cursor (abierto, cerrado, que datos contiene etc...) dejando la bd pillada, yo personalmente lo que hago es crear una variable que contenga el cursor en la función en la voy a utilizarla, trabajo con ella y seguidamente la cierro, es más procuro tener en un code module todas las funciones que tienen que ver con la bd otro code module con funciones que me vienen bien etc...
De esta manera creo que tengo todo un poquito mas controlado, quizás alguien nos de una idea aún mejor.
 

TheFalcon

Active Member
Licensed User
Longtime User
Para nada toda critica constructiva es bienvenida jeje, si tengo declarado el cursor en el proces_global del MAIN, soy mu burro y lo meto todo en el código no se me a dado nunca bien hacer funciones ni módulos jejeje, pero voy a cambiar el código como me comentas mediante code module, que ahora tengo 3 dias libres haber si ordenándolo se solventa ese problema, probare y ya comento aquí.
 

TheFalcon

Active Member
Licensed User
Longtime User
Ya se por que no me va, lo que no se es como solucionarlo, para mi es raro de coj...... Haber si me explico Bien.
El problema no esta en que deje algún SQL sin cerrar pero algo de eso pasara, si cuando genero la tabla al intentar abrir la base de datos me dice que esta corrupta, pero si esa base de datos la muevo de carpeta y luego la saco al PC si me la abre y la tabla esta creada, de echo cuando esta en su sitio ocupa 18kb en cuanto la paso a otra carpeta ocupa 19 que sera con la tabla nueva, no se si tendrá que ver que cuando trabajo en la aplicación aunque la cierre, en la carpeta de la base de datos se me genera la Base de datos BBDD.sql y un archivo con el mismo nombre BBDD.sql-journal. Yo en el botón salir tengo puesto ExitApplication.

PD: la base de datos la muevo con un gestor de archivos "file explorer" de la carpeta donde esta a otra
 

aviario

Active Member
Licensed User
Longtime User
Hola yo la creo así y funciona perfectamente
Midb.Sql1.ExecNonQuery( " CREATE TABLE ULTIMASVENTAS (Cliente TEXT , Referencia TEXT , Fecha INTEGER , Cantidad DOUBLE , Kg DOUBLE , Precio DOUBLE , Dto DOUBLE ) " )
 

dar2o3

Active Member
Licensed User
Longtime User
El archivo ***journal es un archivo temporal que crea sqlite para transacciones y demás es normal.
Un cursor abierto no debería dejar la tabla pillada (ya se que antes e dado a entender que si)

Prueba lo siguiente y dime que te aparece en el log.

B4X:
Dim estadoJournal As String
estadoJournal =SQL1.ExecQuerySingleResult("PRAGMA Journal_mode")
Log("Estado de Journal: " & estadoJournal )

Según la documentación de sqlite:
The OFF journaling mode disables the rollback journal completely. No rollback journal is ever created and hence there is never a rollback journal to delete. The OFF journaling mode disables the atomic commit and rollback capabilities of SQLite. The ROLLBACK command no longer works; it behaves in an undefined way. Applications must avoid using the ROLLBACK command when the journal mode is OFF. If the application crashes in the middle of a transaction when the OFF journaling mode is set, then the database file will very likely go corrupt.
 
Top