Spanish [SOLUCIONADO] Error en BD SQL al crear tabla

Discussion in 'Spanish Forum' started by TheFalcon, Aug 6, 2016.

  1. TheFalcon

    TheFalcon Active Member Licensed 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.

    Code:
    SQL1.ExecNonQuery("CREATE TABLE tab1 (sum NUMBER, id NUMBER)")
    Code:
    SQL1.ExecNonQuery("CREATE TABLE Opciones (SaveSD TEXT)")
    Code:
    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
     
  2. TheFalcon

    TheFalcon Active Member Licensed 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
     
  3. vbmundo

    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..
    Saludos
     
    TheFalcon likes this.
  4. dar2o3

    dar2o3 Active Member Licensed User

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

    TheFalcon Active Member Licensed User

    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
    Code:
    CREATE TABLE Opciones (SaveSD TEXT)
    me lo añade perfecto, el problema es cuando en la aplicación pongo
    Code:
    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.



    Code:
    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


    Code:
    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
     
  6. josnav

    josnav Member Licensed User

    Pon la cadena de conexión. Sube la BBDD corrupta que le echemos un vistazo también.
     
    TheFalcon likes this.
  7. dar2o3

    dar2o3 Active Member Licensed 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.

    Code:
    Sub creatabla(nombretabla As String, campo As String, tipo As StringAs 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

    Code:
    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: Aug 15, 2016
    TheFalcon likes this.
  8. TheFalcon

    TheFalcon Active Member Licensed 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
     
  9. dar2o3

    dar2o3 Active Member Licensed 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: Aug 14, 2016
  10. dar2o3

    dar2o3 Active Member Licensed 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 likes this.
  11. TheFalcon

    TheFalcon Active Member Licensed 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 .


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

    dar2o3 Active Member Licensed 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 likes this.
  13. TheFalcon

    TheFalcon Active Member Licensed 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

    Code:
    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:

    Code:
    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.
     

    Attached Files:

  14. dar2o3

    dar2o3 Active Member Licensed User

    Te falta en la función DBload

    Code:
    cursor1.close

    después del bucle para cerrar el cursor.
     
    TheFalcon likes this.
  15. TheFalcon

    TheFalcon Active Member Licensed 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
     
  16. dar2o3

    dar2o3 Active Member Licensed 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 likes this.
  17. TheFalcon

    TheFalcon Active Member Licensed 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í.
     
    dar2o3 likes this.
  18. TheFalcon

    TheFalcon Active Member Licensed 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
     
  19. aviario

    aviario Active Member Licensed 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 ) " )
     
    TheFalcon likes this.
  20. dar2o3

    dar2o3 Active Member Licensed 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.

    Code:
    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.
     
    TheFalcon likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice