【问题标题】:SqLite c++, can create database but can't insert anthing to a tableSqlLite c++,可以创建数据库但不能向表中插入任何东西
【发布时间】:2020-09-06 06:16:02
【问题描述】:

我正在尝试创建一个将数据从 QLineEdit 附加到 SqLite db 的函数,问题是,我设法创建了数据库和表,但每次我尝试添加实际数据时,程序它无法写入数据库,即使实际数据库正在使用,我使用来自 QsqlQuery 的prepare() 创建语句,然后使用bindValue() 添加实际变量,我不能使用 QDebug 它根本不会显示任何内容为什么我使用了太多的 QmessageBox()

欢迎提出任何想法!

#include "Pantalla_Principal.h"
#include "ui_Pantalla_Principal.h"
#include <QWidget> // usar el widget
#include <QLabel> // usar label
#include <QObject>

#include <QDebug> // hacer debug
#include <QSqlError> //hacer debug sql


//#include "libusb.h"  // libreria para leer USB
//#include "../mariadb++/account.hpp"  // crea las conecciones a la base de datos mariadb
//#include "../mariadb++/connection.hpp" // maneja las conecciones
#include <QSqlDatabase> // crea conecciones a base de datos
#include <QSqlTableModel> // tabla de una sola columna
#include <QSqlRelationalTableModel> // tablas de varias columnas
#include <QSqlQuery> // hace las busquedas y agrega data a los registros
#include <QMessageBox> // crea los mensajes de advertencia
 ....
 ....
 ....

void Pantalla_Principal::Nuevo_Registro_Boletas(){
    wpp.setupUi(this);

    //obtener info del formulario boletas
    QString nombre=wpp.Nombre_Prod_edit->text();  
    QString apellido1=wpp.Apellido1_Prod_edit->text();
    QString apellido2=wpp.Apellido2_Prod_edit->text();
    QString predio=wpp.Predio_Nombre_edit->text();
    QString ubicacion=wpp.Predio_Ubicacion_edit->text();
    QString chofer=wpp.Nombres_Chofer_edit->text();
    QString c_apellido1=wpp.Apellido1_Chofer_edit->text();
    QString c_apellido2=wpp.Apellido2_Chofer_edit->text();
    QString placas=wpp.Placas_Camion_edit->text();
    QString color=wpp.Camion_Color_edit->text();
    QString tipo=wpp.Camion_Tipo_edit->text();
    QString apellidos = apellido1+" "+apellido2;

  //  variables para MYSQL
  //  QString host_name="127.0.0.1";
    QString name_db="CICLO-OI-19-20.db"; //  Base de Datos del Ciclo
  //  QString user="root";
  //  QString pass="agroindustrias";  // poner el nombre de usuario y pass de acuerdo a la base de datos
  //  int port=3306;

    //accesa a la base de Datos MariaDB usando QSql
    if (!QSqlDatabase::isDriverAvailable("QSQLITE")){
        QMessageBox::critical( this, "Error de Base Datos", "\n\n El driver SQL no esta disponible");
    }

    QSqlDatabase mData=QSqlDatabase::addDatabase("QSQLITE"); // pones el tipo de driver de la db, en este caso QMYSQL
       mData.setDatabaseName(name_db); 
    //   mData.setHostName(host_name); //pon  el nombre o direccion del host
    //   mData.setPort(port); // puerto al que llamar
    //   mData.setUserName(user);
    //   mData.setPassword(pass);  

    if (!mData.open()){
        QMessageBox::critical( this, "Error de Base Datos", "\n\nBase de Datos no encontrada");
    }

    // llena la base de datos usando QSqlQuery
    QSqlQuery valor;
    valor.exec("CREATE TABLE IF NOT EXISTS boletas "
               "(Folio_Num INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
               "Chofer_Nombre VARCHAR(255) NOT NULL, Chofer_Apellidos VARCHAR(255) NOT NULL,"
               "Placas VARCHAR(255) NOT NULL,"
               "Camion_Color VARCHAR(255) NOT NULL, Camion_Tipo VARCHAR(255) NOT NULL,"
               "Peso_Bruto INTEGER NOT NULL, Peso_Tara INTEGER NOT NULL,"
               "Peso_Neto INTEGER NOT NULL, Humedad DOUBLE NOT NULL,"
               "Retenciones DOUBLE NOT NULL, Impuresas DOUBLE NOT NULL )");
    if(!valor.exec()){
        QMessageBox::warning(this,"Error","\n\n No se pudo crear las tablas");
    }else
        QMessageBox::information(this,"Logro","\n\n Tabla Creada");

    valor.prepare( "INSERT INTO boletas (Folio_Num, Chofer_Nombre, Chofer_Apellidos, Placas, Camion_Color,"
                   "Camion_Tipo, Peso_Bruto, Peso_Tara, Peso_Neto, Humedad, Retenciones, Impuresas)" 
                   "VALUES (:Folio_Num, :Chofer_Nombre, :Chofer_Apellidos, :Placas, :Camion_Color, :Camion_Tipo,"
                   ":Peso_Bruto, :Peso_Tara, :Peso_Neto, :Humedad, :Retenciones, :Impuresas)" );

    // valor.prepare( "INSERT INTO boletas (Chofer_Nombre) VALUES (:Chofer_Nombre)");              
    valor.bindValue(":Chofer_Nombre", nombre);
    valor.bindValue(":Chofer_Apellidos", apellidos); // unir las dos variables
    valor.bindValue(":Placas", predio);
    valor.exec();
    //QSqlQuery valor;
    //valor.exec("");

    if (!valor.exec()){
        QMessageBox::warning( this, "Error", "\n \n No se Pudo Guardar");
    }
    else{
        QMessageBox::information( this, "Nuevo Registro", "\n \n Se a creado un Nuevo Registro con exito");
    }

    mData.close();
}

编辑1:

我像大家告诉我的那样编辑,并为每个占位符添加更多 bindvalue(),如果我直接传递它记录的信息而不是来自变量 valor.bindValue(":Retenciones", "retencio");,可悲的是,如果我删除数据库,它不会创建再次数据库,一旦记录,除非我重新启动程序,否则我无法创建任何新记录,我必须使用 2 valor.exec() 才能使其工作

我倒退了一步,知道我在搞砸什么吗?

QSqlQuery valor;
valor.prepare("CREATE TABLE boletas "
           "(Folio_Num INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
           "Chofer_Nombre VARCHAR(255) NOT NULL, Chofer_Apellidos VARCHAR(255) NOT NULL,"
           "Placas VARCHAR(255) NOT NULL,"
           "Camion_Color VARCHAR(255) NOT NULL, Camion_Tipo VARCHAR(255) NOT NULL,"
           "Peso_Bruto INTEGER NOT NULL, Peso_Tara INTEGER NOT NULL,"
           "Peso_Neto INTEGER NOT NULL, Humedad DOUBLE NOT NULL,"
           "Retenciones DOUBLE NOT NULL, Impuresas DOUBLE NOT NULL )");
valor.exec();
valor.prepare( "INSERT INTO boletas ( Chofer_Nombre, Chofer_Apellidos, Placas, Camion_Color,"
               "Camion_Tipo, Peso_Bruto, Peso_Tara, Peso_Neto, Humedad, Retenciones, Impuresas)" 
               "VALUES (:Chofer_Nombre, :Chofer_Apellidos, :Placas, :Camion_Color, :Camion_Tipo,"
               ":Peso_Bruto, :Peso_Tara, :Peso_Neto, :Humedad, :Retenciones, :Impuresas)" );  
valor.bindValue(":Chofer_Nombre", nombre);
valor.bindValue(":Chofer_Apellidos", apellidos); // unir las dos variables
valor.bindValue(":Placas", predio);
valor.bindValue(":Camion_Color", color);
valor.bindValue(":Camion_Tipo", tipo);
valor.bindValue(":Peso_Bruto", "bruto" );
valor.bindValue(":Peso_Tara", "tara");
valor.bindValue(":Peso_Neto", "neto");
valor.bindValue(":Humedad", humedad);
valor.bindValue(":Retenciones", "retencio");
valor.bindValue(":Impuresas", "impuresas");
valor.exec();

好的,我确实删除了所有内容并从头开始,问题在于两件事:

  1. QlineEdit 每次都传递它的空字符串
  2. if who 检查表是否有效并正在停止准备函数以创建查询

我确实设法通过简化代码来修复 sqlite 方面,为了安全起见,我将所有内容记录到文本文件中,qline 编辑仍然给我一个空字符串,将尝试检查它

【问题讨论】:

  • 您已经为插入创建了一个准备好的语句,但只绑定了三个占位符的值::Chofer_Nombre:Chofer_Apellidos:Placas。您也需要对其他占位符执行相同操作::Camion_Color:Camion_Tipo:Peso_Bruto:Peso_Tara:Peso_Neto:Humedad:Retenciones:Impuresas

标签: c++ sqlite qt


【解决方案1】:

首先,尝试打印valor.lastError().text(),看看错误文本是什么(要使用这个成员,应该包含QSqlError)。您的命令中有两个主要问题:

  1. valor.exec() 正在执行两次。我建议删除此行,只保留if (!valor.exec()){ 行。
  2. 您在 prepare 命令中提到了 12 项,但其中只有 3 项是绑定值。

编辑1:

你可以按如下方式让你的代码整洁,看看是哪一行导致了错误:

//obtener info del formulario boletas
    QString nombre= "nombre";
    QString apellido1= "apellido1";
    QString apellido2= "apellido2";
    QString predio= "predio";
    QString ubicacion= "ubicacion";
    QString chofer= "chofer";
    QString c_apellido1= "c_apellido1";
    QString c_apellido2= "c_apellido2";
    QString placas= "placas";
    QString color= "color";
    QString tipo= "tipo";
    QString apellidos = apellido1+" "+apellido2;


      QString name_db="CICLO-OI-19-20.db"; //  Base de Datos del Ciclo

      QSqlDatabase mData=QSqlDatabase::addDatabase("QSQLITE"); // pones el tipo de driver de la db, en este caso QMYSQL
      mData.setDatabaseName(name_db);
      if (mData.open()) {

          // llena la base de datos usando QSqlQuery
          QSqlQuery valor;
          if (valor.exec("CREATE TABLE IF NOT EXISTS boletas "
                         "(Folio_Num INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
                         "Chofer_Nombre VARCHAR(255) NOT NULL, Chofer_Apellidos VARCHAR(255) NOT NULL,"
                         "Placas VARCHAR(255) NOT NULL,"
                         "Camion_Color VARCHAR(255) NOT NULL, Camion_Tipo VARCHAR(255) NOT NULL,"
                         "Peso_Bruto INTEGER NOT NULL, Peso_Tara INTEGER NOT NULL,"
                         "Peso_Neto INTEGER NOT NULL, Humedad DOUBLE NOT NULL,"
                         "Retenciones DOUBLE NOT NULL, Impuresas DOUBLE NOT NULL )")) {

              //---> Table created successfully ---> Now, insert data

              if (valor.prepare( "INSERT INTO boletas ( Chofer_Nombre, Chofer_Apellidos, Placas, Camion_Color,"
                                 "Camion_Tipo, Peso_Bruto, Peso_Tara, Peso_Neto, Humedad, Retenciones, Impuresas)"
                                 "VALUES (:Chofer_Nombre, :Chofer_Apellidos, :Placas, :Camion_Color, :Camion_Tipo,"
                                 ":Peso_Bruto, :Peso_Tara, :Peso_Neto, :Humedad, :Retenciones, :Impuresas)" )) {

                  //Query prepared successfully ---> Now, bind values
                  valor.bindValue(":Chofer_Nombre", nombre);
                  valor.bindValue(":Chofer_Apellidos", apellidos); // unir las dos variables
                  valor.bindValue(":Placas", predio);
                  valor.bindValue(":Camion_Color", color);
                  valor.bindValue(":Camion_Tipo", tipo);
                  valor.bindValue(":Peso_Bruto", "bruto" );
                  valor.bindValue(":Peso_Tara", "tara");
                  valor.bindValue(":Peso_Neto", "neto");
                  valor.bindValue(":Humedad", 12);
                  valor.bindValue(":Retenciones", "retencio");
                  valor.bindValue(":Impuresas", "impuresas");

                  if(valor.exec()){

                      qDebug() << "data inserted successfully!";
                  } else {

                      qDebug() << "Unable to execute query because: " << endl << valor.lastError().text();
                  }
              } else {

                  qDebug() << "Unable to prepare the query because: " << endl << valor.lastError().text();
              }
          } else {

              qDebug() << "Unable to create the table because: " << endl << valor.lastError().text();
          }

          mData.close();
      } else {

          qDebug() << "Unable to open database because: " << endl << mData.lastError().text();
      }

【讨论】:

  • 请注意,数据类型必须与您在建表命令中定义的类型相匹配。例如,您已将“Peso_Bruto”定义为 INTEGER,但在 bindValue 中,您将 QString 传递给它。请在所有绑定值中解决此问题,然后查看问题是否解决。
  • 嗯,这很奇怪,humedad 列声明为整数双精度,但我可以传递一个字符串,因为它是直接声明的,而不是作为变量传递的,还有 retenciones、impuresas 等。我对这个数据库有奇怪的行为
  • 虽然您可以传递一个字符串而不会出现任何编译错误,但是如果您使用valor.lastError().text() 打印最后一个错误(绑定值之后),您将看到Qt 返回一个数据类型不匹配错误。请参阅我的 Edit1。
  • 经过多次尝试后,我不得不将valor.lastError().text() 写入文本文件,问题是:No query Unable to fetch row,基本上问题出在 sqlite侧面,我确实尝试使用addBinderValue() 和问号占位符,不是运气,我会检查 sql 教程并尝试找出问题所在
  • 哪一行返回该错误No query Unable to fetch row*
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 2021-09-24
  • 2019-09-25
相关资源
最近更新 更多