https://foro.gambas-es.org/viewtopic.php?f=3&t=60
-----------------------------------
Manuel
Martes, 22 Septiembre 2009, 18:26

Problema Al Insetar Un Nuevo Registro
-----------------------------------
Hola.
Estoy hacinedo una pequeña aplicación. 
Trabajo con Sqlite3.
Me conecto a la base de la siguiente forma:
************************************
'CONEXION DE LA BASE DE DATOS
PRIVATE FUNCTION ConectarBase() AS Boolean
  
  IF hConn <> NULL THEN RETURN FALSE
  hConn = NEW Connection
  
  hConn.Host = "/home/manuel/Gambas/Registro"
  hConn.Name = "datos.db"
  hConn.Type = "sqlite3"
  
  TRY hConn.Open()
    IF ERROR THEN 
      hConn = NULL
      Message.Error("Error al conectar la base de datos")
      RETURN FALSE
    END IF
    RETURN FALSE
END

**************************
La base se conecta bien y muestro los datos en la pantalla mediante un ColumView.

Para insertar los datos uso la siguiente instrucción:
****************************************
' Añadir un nuevo registro.
PUBLIC SUB BtnAceptar_Click()
TRY hconn.EXEC("insert into datos values (&1,&2,&3,&4,&5)", TxtUsuario.text, TxtNMatricula.Text, TxtSeccion.Text, TxtPlanta.Text, TxtObservaciones.Text)
  
 CATCH 
    Message.Error("No se han podido guardar los datos")
END
*****************************
Los datos no se guardan.  Pero no sale el mensaje de error
Los campos en la tabla estan definidos como string.

¿alguna sugerencia?
Saludos.


-----------------------------------
soplo
Martes, 22 Septiembre 2009, 18:49

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
Como no conozco sqlite es posible que ese insert que has puesto sea correcto aunque a mi no me lo parece. Sin embargo si estuviera mal te daría algún error de sqlite. Tu dices que no te dice nada ni se te va al catch ni nada así que lo que parece es que la instrucción se ejecuta correctamente pero que no inserta nada.

[code linenumbers=false]TRY hconn.EXEC("insert into datos values (&1,&2,&3,&4,&5)", TxtUsuario.text, TxtNMatricula.Text, TxtSeccion.Text, TxtPlanta.Text, TxtObservaciones.Text) [/code]

Creo que una alternativa es hacer el insert con gambas y pasar del lenguaje específico de sqlite.

[code linenumbers=false]Dim Rs as result
try Rs=hconn.create(datos)
Rs!campo1=txtusuario.text
Rs!campo2=txtnmatricula.text
Rs!campo3=txtseccion.text
...
Rs.update[/code]

Si utilizas estas técnicas el dia que te cambies de sqlite a mysql u otra solo tendrás que cambiar el type en la conexion, y los insert, select, update, delete funcionarán igual.


-----------------------------------
jguardon
Martes, 22 Septiembre 2009, 18:56

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
Hola Manuel, bienvenido

Si mirar mucho el código, te recomiendo que quites el TRY y el CATCH del procedimiento del botón de añadir registro, para que el depurador de detenga en donde esté el error. 
Una vez que se muestra el error, al menos te dará una pista de lo que ocurre, y al cerrar el mensaje mientras el programa está pausado,
podrás seleccionar variables y/o funciones para ver los datos que contienen en ese momento.

A mí me parece que cuando vas a hacer el INSERT, está queriendo introducir datos en la base de datos y no en una tabla de esa bd (al menos, tienen el mismo nombre), y al tener la instrucción TRY, no muestra el error. 

Saludos


-----------------------------------
jguardon
Martes, 22 Septiembre 2009, 19:11

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
[quote user="soplo" post="154"]Como no conozco sqlite es posible que ese insert que has puesto sea correcto aunque a mi no me lo parece. 

Creo que una alternativa es hacer el insert con gambas y pasar del lenguaje específico de sqlite.
[/quote]
No hay nada específico de sqlite en esa sentencia, simplemente se nombran los parámetros como variables &1, &2... y a continuación se ponen los parámetros separados con comas. La ventaja es que no es necesario ninguna sintaxis adicional por ejemplo para fechas, cadenas o números.
[quote]
Si utilizas estas técnicas el dia que te cambies de sqlite a mysql u otra solo tendrás que cambiar el type en la conexion, y los insert, select, update, delete funcionarán igual.[/quote]

Soplo, la sentencia es correcta, al menos en la forma -no sé si en el nombre de la tabla lo será.

El código que has puesto tú es válido, pero a mi gusto, menos funcional. Ambos son compatibles con los diferentes drivers de bd.


-----------------------------------
david
Martes, 22 Septiembre 2009, 23:04

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
creo que el error esta en que no abres la basa de datos para hacer el insert ito por ejemplo este es tu codigo
*******************
La base se conecta bien y muestro los datos en la pantalla mediante un ColumView.

Para insertar los datos uso la siguiente instrucción:
****************************************
' Añadir un nuevo registro.
PUBLIC SUB BtnAceptar_Click()
--------------AQUI ES DONDE TIENES QUE CONECTARLA PARA QUE LO RECONOZCA POR EJEMPLO EN TU CASO SERIA ASIN
  IF ConectarBase() THEN RETURN 
------------------------------------------------- PRUEBA ESTO HABER SI TE SIRVE

TRY hconn.EXEC("insert into datos values (&1,&2,&3,&4,&5)", TxtUsuario.text, TxtNMatricula.Text, TxtSeccion.Text, TxtPlanta.Text, TxtObservaciones.Text)
  
 CATCH
    Message.Error("No se han podido guardar los datos")
END


-----------------------------------
soplo
Miercoles, 23 Septiembre 2009, 14:51

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
[quote]El código que has puesto tú es válido, pero a mi gusto, menos funcional. Ambos son compatibles con los diferentes drivers de bd.[/quote]
Pero ese método es mas transparente al no depender del lenguaje de base de datos. Si hace así los insert, updates, deletes y select el dia que quiera cambiar por ejemplo de sqlite a mysql bastará con cambiar el type y el usuario de la conexión y todo su código le seguirá funcionando.

Lo expliqué en el post del objeto connection y merece la pena. Es el método nativo de gambas y es eficiente.


-----------------------------------
david
Miercoles, 23 Septiembre 2009, 15:11

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
[b]Manuel[/b],
yo tambien cambiaria algo de la conexion a la base hazla publica para cuando programes se te se mas facil leer
tu la tienes asin
PRIVATE FUNCTION ConectarBase() AS Boolean 
pon la sin que es mas facil para los programas reconocerlo
PUBLIC FUNCTION ConectarBase() AS Boolean
es un cosejo como siempre tu elijes


-----------------------------------
Manuel
Sabado, 26 Septiembre 2009, 22:46

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
Hola 
Gracias a todos por la respuesta.
He encontrado una solución un poco chapucera, pero funciona.
El código queda de la siguiente forma:
**********************
[code linenumbers=false syntax=gambas]' Añadir un nuevo registro.
PUBLIC SUB BtnAceptar_Click()
Dim P_Usuario,P_seccion,P_Observaciones as String
Dim P_Matricula, P_Planta as Integer

P_Usuario =TxtUsuario.text
P_Matricula = TxtNMatricula.Text
P_Seccion =TxtSeccion.Text
P_Planta =TxtPlanta.Text
P_Observaciones =TxtObservaciones.Text)

db.EXEC("insert into datos (Usuario, Matricula, Seccion, Planta, Observaciones)values (' "& TxtUsuario.text &" ', ' "& Matricula &" ', ' "& Seccion &" ', ' "& TxtPlanta  &" ', ' "& Observaciones &" ')")
  
END [/code]
****************************
Como veis hay que declarar una variable que va a contener el valor de TextBox , porque si pongo (por ejemplo)TxtUsuario.text, lo que se grabara es TxtUsuario.text y no el valor que contenga.
Saludos.
Manuel


-----------------------------------
jguardon
Sabado, 26 Septiembre 2009, 23:37

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
[quote user="Manuel" post="221"]
[code linenumbers=false syntax=gambas]PUBLIC SUB BtnAceptar_Click()
Dim P_Usuario,P_seccion,P_Observaciones as String
Dim P_Matricula, P_Planta as Integer

P_Usuario =TxtUsuario.text
P_Matricula = TxtNMatricula.Text
P_Seccion =TxtSeccion.Text
P_Planta =TxtPlanta.Text
P_Observaciones =TxtObservaciones.Text[/code]
[/quote]

A mi me parece que es lo mismo... para que lo entiendas, esas variables toman los valores de los textbox en el momento de pulsar el botón, es decir, que da igual que pongas en la sentencia sql las variables o el texto de los textbox porque son iguales en ese preciso momento. ([i]A menos que no estés usando las mismas variables, porque ahora que me fijo, las variables no coinciden, unas empiezan con P_ y las que usas en el sql no[/i])

[quote]db.EXEC("insert into datos (Usuario, Matricula, Seccion, Planta, Observaciones)values (' "& [color=#e50000]TxtUsuario.text[/color] &" ', ' "& Matricula &" ', ' "& Seccion &" ', ' "& TxtPlanta  &" ', ' "& Observaciones &" ')")[/quote]

Acabas de demostrar lo que digo, jeje. Si te fijas, el primer campo que insertas es el TxtUsuario.Text, no la variable que asignaste antes ¡y funciona!.
Es lógico, como también lo es usar la sintaxis inicial, con parámetros &1, &2... ahora que parece que ya tienes abierta la conexión antes del insert. 

Otra cosa más: el motor sqlite3,  realmente no distingue entre los tipos de datos que almacena, aunque tu  digas si es entero, fecha o cadena; internamente los trata por [b]afinidad[/b], es decir, si tratas de almacenar un número en un campo de texto, lo convierte a texto, y si el campo está definido como integer, tratará de convertirlo y si no puede lo tratará como texto.

No obstante, te voy a mostrar el código que uso en mi programa de log que ya conoces, para que veas lo que digo con un insert mucho más complejo:

[code linenumbers=false syntax=gambas]PRIVATE SUB logQSO()
    DIM sql AS String
    DIM modo AS String = cboModo.Text
    DIM dist AS Float = CFloat(Replace(lblDist.Text, ",", "."))
    IF modo = "LSB" OR modo = "USB" THEN modo = "SSB"
    
    IF connDB() THEN RETURN 'conecta a la bd
    sql = "INSERT INTO log VALUES (&1,&2,&3,&4,&5,&6,&7,&8,&9,&10,&11,&12,&13,&14,&15,&16,&17,&18," &
              "&19,&20,&21,&22,&23,&24,&25,&26,&27,&28,&29,&30,&31,&32,&33,&34,&35,&36,&37,&38);"
    
    dbLog.cnLog.Exec(sql, "", vFecha.Value, vHora.Text, vHora2.Text, txtCall.Text, parseFreq(txtFreq.Text),
                    parseFreq(txtFreq2.Text), cboBanda.Text, modo, cboPropa.Text, txtRSTr.Text,
                    txtRSTe.Text, txtNameQSO.Text, txtLocQSO.Text, txtQTHqso.Text, txtComment.Text, QSLsent(),
                    QSLrec(), dteQSLe.Value, dteQSLr.Value, txtMgrQSO.Text, c.pfx, c.continent, c.cqz, c.ituz, 
                    txtState.Text, txtCounty.Text, txtIOTA.Text, ini["Estacion/QRZ"], txtPwr.Text, ini["Estacion/Locator"],
                    txtSatName.Text, txtSatMode.Text, lblEmail.Text, c.entity, c.number, txtTPEA.Text, dist)             
    fillData()
    
    CATCH     
        Message.Error(("Error loging QSO\n") & Error.Text & "\n" & Error.Where)    
END[/code]

Por cierto, para los que no lo sepan, aquí se ve la forma de romper las líneas largas para mejor presentación del código:
Las sentencias que contienen comas se pueden continuar en otra línea a partir de una coma, y para hacerlo con cadenas,
basta cerrar la cadena con las dobles comillas y un ampersand [b]&[/b] y continuar la línea abriendo las comillas (teniendo en 
cuenta los espacios).

Espero que sirva de ayuda, saludos


-----------------------------------
david
Domingo, 27 Septiembre 2009, 19:47

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
cierto es lo mismo, yo no lo tengo declarado y a mi se me entra los registros


-----------------------------------
jolubae
Lunes, 30 Noviembre 2009, 16:51

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
buenos tardes Marcos, aqui te doy mi humilde ayuda
creo que le das muchas vueltas mira:

create una variable en 

PRIVATE contacto AS Result (esto te mostrara el resultado de tu tabla)

y esto va debajo de tu RETURN FALSE, colocando 
ELSE
contacto = hconn.Exec("Select * from tutabla")
IF contacto.Available THEN Mostrar
END IF

tedebes crear esto para mostrar tus datos

PUBLIC SUB Mostrar()
txtusuario.text = tutabla["Usuario"]
txtmatricula.text = tutabla["Matricula"]
txtseccion.text = tutabla["Sección"]
txtplanta.text = tutabla["Planta"]
txtobservacion = tutabla["Observación"]
END

a parte del boton de nuevo create dos, uno que guarda y otro que cancela 

PUBLIC SUB btnNuevo_Click()
Btnguardar.Visible = TRUE
Btncancelar.Visible = TRUE
txtusuario.text = ""
txtmatricula.text = ""
txtseccion.text = ""
txtplanta.text = ""
txtobservaciones.text = ""
END

luego:

PUBLIC SUB Btnguardar_Click()
DIM VarResult AS Result
VarResult = hconn.Create("tutabla")
VarResult["Usuario"] = txtusuario.Text
VarResult["Matricula"] = txtmatricula.Text
VarResult["Sección"] = txtseccion.Text
VarResult["Planta"] = txtplanta.Text
VarResult["Observaciones"] = txtobservaciones.Text
VarResult.Update
contacto = hconn.Exec("Select * from tutabla")
Btnguardar.Visible = FALSE
Btncancelar.Visible = FALSE
END

PUBLIC SUB Btncancelar_Click()
Btnguardar.Visible = FALSE
Btncancelar.Visible = FALSE
Mostrar
END

bueno camarada espero que esto te funcione, sin embargo no es todo mio tambien tiene que ver mucho mi camarada Pablo,

saludo.......


-----------------------------------
david
Miercoles, 02 Diciembre 2009, 23:15

Re: Problema Al Insetar Un Nuevo Registro
-----------------------------------
manuel y si pruebas esto a lo mejor es una tonteria pero puede servir
tu tienes esto
TRY hconn.EXEC(insert y lo demas
pon esto
TRY hconn.exec( insert y lo demas
 una vez tube el mismo error


