INSERT do bazy danych - query->exec(); nie działa

0

Witam, mam problem, ogólnie, działało przez chwilkę, aż nie zacząłem usprawniać kodu, a teraz sam nie wiem czego to jest wina. Mam nadzieję że czyjeś sprawne oko zauważy błąd.

funkcja wyświetlająca tabele

{
    query = new QSqlQuery(database);
    query->exec("SELECT * FROM products");

    model = new MySqlTableModel(this,database);
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->mySetQuery(*query);
    model->select();

    blobDecoder = new SqlBlobDecoderModel(this);
    blobDecoder->setSourceModel(model);
    blobDecoder->setImageColumn(blobDecoder->imageColumn());


    ui->tableView->setModel(blobDecoder);
        ui->tableView->hideColumn(0);
        ui->tableView->hideColumn(3);
        ui->tableView->hideColumn(10);
        ui->tableView->resizeColumnsToContents();
        ui->tableView->setColumnWidth(1,64);
        ui->tableView->setColumnWidth(2,222);
        ui->tableView->setColumnWidth(8,83);
        ui->tableView->setColumnWidth(9,75);
        ui->tableView->resizeRowsToContents();
        ui->tableView->setSortingEnabled(true);
        ui->tableView->sortByColumn(8,Qt::DescendingOrder);
}

w niej przycisk do dodawania

Product product(this);
    product.setModal(true);
    product.exec();

    if(product.isCanceled)
    {
        QMessageBox::warning(this,"Product adding error!","Can't insert product to database. Try again.");
    }
    else {
        query->prepare("INSERT INTO products (img,name,notes,kcal,carbonates,proteins,fats,weight,date,type)"
                       "VALUES(?,?,?,?,?,?,?,?,?,?)");
        query->addBindValue(product.getImageToByteArray());
        query->addBindValue(product.getName());
        query->addBindValue(product.getNotes());
        query->addBindValue(product.getKcal());
        query->addBindValue(product.getCarbonates());
        query->addBindValue(product.getProteins());
        query->addBindValue(product.getFats());
        query->addBindValue(product.getWeight());
        query->addBindValue(product.getDate());
        query->addBindValue(product.getType());
        if(query->exec())
        {
            QMessageBox::information(this,"Succefully added","Succefully added product to the database!");
        }
        else {
            QMessageBox::warning(this,"Cannot add product!","Try again!");
        }

    }

table_display();

}

i klasa od produktu który dodajemy

QByteArray Product::getImageToByteArray()
{
    QBuffer buff(&bytearray);
    buff.open(QIODevice::WriteOnly);
    image.save(&buff,"PNG");
    if ((bytearray.isEmpty()) || (bytearray.isNull()))
    {
        bytearray.clear();
    }
     return bytearray;
}
QString Product::getName()
{
    return name;
}

QString Product::getNotes()
{
    return notes;
}
int Product::getKcal()
{
    return kcal;
}
int Product::getCarbonates()
{
    return carbonates;
}
int Product::getProteins()
{
    return proteins;
}
int Product::getFats()
{
    return fats;
}
int Product::getWeight()
{
    return weight;
}
QDate Product::getDate()
{

    return ui->caldate->selectedDate();
}
int Product::getType()
{
    return type;
}
bool Product::getAll()
{  

    name = ui->lnname->text();
    if ((name.isEmpty()) || (name.isNull()))
    {

        ui->lnname->setStyleSheet(
                    "QLineEdit { "
                    "background-color:rgb(133, 133, 133);}");
        QMessageBox::warning(this,"Adding product","Name can't be empty!");
        return false;
    }
    else
    {
        name = ui->lnname->text();
        notes = ui->lnnotes->text();

        ///KCAL VALIDATION
        int kcal1 = ui->lnkcal->text().toInt();
        if ((kcal1>=0)&&(kcal1<1000))
            kcal = kcal1;
        else kcal=0;

        ///CARBONATES VALIDATION
        int carbonates1 = ui->lncarbonates->text().toInt();
        if ((carbonates1>=0)&&(carbonates1<100))
            carbonates = carbonates1;
        else carbonates =0;

        ///PROTEINS VALIDATION
        int proteins1 = ui->lnproteins->text().toInt();
        if ((proteins1>=0)&&(proteins1<100))
            proteins = proteins1;
        else proteins =0;

        ///FATS VALIDATION
        int fats1 = ui->lnfats->text().toInt();
        if ((fats1>=0)&&(fats1<100))
            fats = fats1;
        else fats =0;

        ///WEIGHT VALIDATION
        int weight1 = ui->lnweight->text().toInt();
        if ((weight1>=0)&&(weight1<1000000000))
            weight = weight1;
        else weight =0;



        return true;
    }
}
void Product::on_btnok_clicked()
{
    if(getAll())
    {
        isCanceled=false;
        accept();
    }

}
void Product::on_btncancel_clicked()
{
    isCanceled=true;
    accept();
}

I wyskakuje error od if(query->exec())

Tak PS: jak zrobić by QDate i QByteArray dawać do bazy jako NULL gdy są źle wybrane? date={} czy date=QDate() czy co bo date=NULL ani nullptr nie działają a ja w bazie mam je na default null

Załącznik z bazy danych. Ma to być ustawione na nulle tak jak jest? Bo chcę ogólnie żeby jak użytkownik nic tam nie wybierze nie zaznaczy to żeby nie było nic, czysto, null, żeby potem mi sortingu nie mieszało, to tak ma być czy jakoś zmieinić?

0

jaki error?

0

Najwyższa pora Bracie @Xezolpl postawić sobie lokalnie jakieś repo SVNa, albo Git-a, i przy okazji nauki programowania uczyć się także posługiwania repozytorium kodu. To pomoże na przypadki zrypania kodu, pozwoli na śledzenie zmian oraz w razie czego proste odkręcanie ich.

Dobra, widzę, że trzeba zacząć od podstaw.
Posługiwanie się bazami danych w Qt wymaga najsampierw poprawnego otwarcia bazy. Dopiero potem można tworzyć wszelakie obiekty QSql<coś tam>. Ponadto nieocenioną pomocą jest QSqlError do którego dobierzesz się przez QSqlDatabase::lastError() oraz QSqlQuery::lastError().

W innym wątku dałem ci klasę akcesora do bazy danych która gwarantowała, że jeśli plik bazy się otworzy to przechowywany w obiekcie QSqlQuery będzie banglał. Tamten kod jest koszmarem jaki popełniłem ucząc się programowania, masz tutaj zoptymalizowaną wersję:

//DatabaseAccessor.h
class DatabaseAccessor
{
public: 
    static QSqlDatabase& getDatabase();
    static QSqlQuery& getQuery();

private:
    QSqlDatabase base;
    QSqlQuery query;

	static DatabaseAccessor& instance();
    DatabaseAccessor();
	~DatabaseAccessor() = default;
};

//DatabaseAccessor.cpp
#include "DatabaseAccessor.h"
DatabaseAccessor::DatabaseAccessor()
{
    QSqlDatabase::addDatabase("QSQLITE");   
    base = QSqlDatabase::database();    
    base.setDatabaseName("./Databases/nazwaTwojejBazy.db");// istotne jest tutaj to ./ aby była ścieżka względem odpalonego .exe
    if (!base.open())
    {
        QMessageBox::warning(nullptr, tr("Error during opening database!"), base.lastError().text());
        exit(0);
    }
	    
    query = QSqlQuery(base);
}

DatabaseAccessor& DatabaseAccessor::instance()
{
	static DatabaseAccessor accessor;
	return accessor;
}

QSqlDatabase& DatabaseAccessor::getDatabase(void)
{
	return instance().database;
}

QSqlQuery& DatabaseAccessor::getQuery()
{
	return instance().query;
}

Przerób swój kod tak, aby w każdym miejscu gdzie potrzebuje skorzystać z QSqlQuery albo QSqlDatabase używał odpowiednio DatabaseAccessor::getQuery() albo DatabaseAccessor::getDatabase() zamiast samemu tworzyć te obiekty. Dzięki temu wyeliminujesz problem niewłaściwej inicjalizacji.
Ponadto w folderze z aplikacją utwórz dodatkowo podfolder Databases, i tam umieść plik z bazą. Przy czym uwaga! Przy odpalaniu spod IDE ścieżka względna do .execa bywa nieco inna, zwykle to jest podfolder budowania \debug albo \release

1 użytkowników online, w tym zalogowanych: 0, gości: 1