I have a project that I transfer from Visual Studio to QtCreator. The compiler changes accordingly. And now the problem with working with the database. In the studio, it all worked, but QtCreator and MinGW do not like what I don’t understand. Specifically, the problem boils down to the fact that when processing a SQL query it does not see the table. If you look through SQLiteManager, then all tables are in place and the query is executed and gives the desired output.

The problem is here:

QVector<QStringList> DbManager::showNotes() { if (MattyNotesDb.isOpen()) { QVector<QStringList> VectorOfNotes; QueryConstructor SelectAll; SelectAll.setTableName(QStringLiteral("Notes")); SelectAll.setOrderByClause("NoteId", Descending); QSqlQuery getNotesQuery; if( getNotesQuery.exec(SelectAll.constructSelectQuery())) // exec возвращает false { while (getNotesQuery.next()) // соответственно тоже возвращает false { QStringList Fields; for (int i = 0;i < 9;i++) { Fields.push_back(getNotesQuery.value(i).toString()); } VectorOfNotes.push_back(Fields); } } else { QMessageBox::critical(NULL, QObject::tr("Error"), getNotesQuery.lastError().text()); // no such table. Unable to execute statement } return VectorOfNotes; } else { showIsNotOpenError(); return QVector<QStringList>(); } } 

Connect to the database:

 bool DbManager::connect(const QString & path) { MattyNotesDb = QSqlDatabase::addDatabase("QSQLITE"); MattyNotesDb.setDatabaseName(path); // path="MattyNotes.sqlite" if(QFile::exists(path)) // true { if (!MattyNotesDb.open()) // open=true, то есть if(false) { QMessageBox::critical(NULL, QObject::tr("Error"), MattyNotesDb.lastError().text()); MattyNotesDb.close(); return false; } return true; } else { return false; } } 

Making a request:

 QString QueryConstructor::constructSelectQuery() { QString ResultQuery = ""; if (TableName != "") { ResultQuery.append("SELECT "); if (WhatToSelectFieldNames.isEmpty()) { ResultQuery.append("*"); } else { for (int i = 0;i < WhatToSelectFieldNames.length()-1;i++) { ResultQuery.append(" " + WhatToSelectFieldNames[i] + ","); } ResultQuery.append(WhatToSelectFieldNames.last()); } ResultQuery.append(" FROM " + TableName + constructWhereEqualsClause() + " " + OrderByClause); } return ResultQuery; // "SELECT * FROM Notes ORDER BY NoteId DESC; " } 

UPD: Problem in file path. If you manually set the full path, then everything works.

one.

  QString PathToDb = QCoreApplication::applicationDirPath() + "/MattyNotes.sqlite"; 

This option eventually sets the PathToDb variable to the value "C: / Users / Matty / Documents / QtCreator / build-MattyNotes-Desktop_Qt_5_7_1_MinGW_32bit-Debug / debug / MattyNo" The folder is correct, but for what reason is it cut off?

2

 QString PathToDb = QDir::currentPath() + "/MattyNotes.sqlite"; 

This option assigns the value "C: /Users/Matty/MattyNotes.sqlite" In general, I wonder where the intermediate folders are.

3

 QString PathToDb = QFileInfo(".").absolutePath() + "/MattyNotes.sqlite"; 

This option gives "C: /Users/MattyNotes.sqlite"

What's happening? How easy is it to specify a relative path, so that everything eventually works on different machines?

And another question: why

 if(QFile::exists(path)) // true if (!MattyNotesDb.open()) // open=true, то есть if(false) 

these lines were true, if in fact the opening of the database did not occur?

  • Make sure you really connect to the database you need. Is the path to the base correct, is there any Russian characters on the way, are there other tables being read? - Cerbo
  • The relative path consists only of the file name: `MattyNotesDb.setDatabaseName (path); // path = "MattyNotes.sqlite" `Is it somewhere that it is implicitly replaced with a full one (maybe there can be such a thing?), there are some gaps, but I don’t use the full path in the code. I'm going to try other tables now. - Matty
  • No, on the other tables the same reaction. - Matty
  • So, ok, transfer to another place with a path without spaces and Russian characters + indicating the full path worked. Then the question is: why does the relative path not work? And why are they being checked for the presence of the file and the opening of the database? - Matty
  • Look in the direction of the source encoding, as far as I remember, gcc expects utf8 by default, and in the studio win1251. Still look at which way the relative unfolds using QFileInfo(path).absoluteFilePath() . - Cerbo

1 answer 1

The request is not assigned a database. Try this:

 QSqlQuery getNotesQuery(MattyNotesDb); 

QSqlQuery :: QSqlQuery (QSqlDatabase db)

UPD. When you run an application from under Qt Creator, the modified environment is applied to the program. The current directory is not the one in which the executable file is located, but one level higher. To find out exactly, write in the .pro file:

 message($$OUT_PWD) 

The program will print the full path. Go there and put your database file. In general, the sqlite driver creates a new database file if the specified one does not exist. Therefore, it may well be that the database has opened, but there is no specified table in it. When you start the application normally, double-clicking on the file uses the normal environment. In this case, the database file should be in the same folder, the necessary DLL files should also be located there (Qt5Core.dll, Qt5Sql.dll, Qt5Widgets.dll, etc.), and the database driver file should be in the sqldrivers folder (qsqlite.dll seems to be. It is located in the $$[QT_INSTALL_PLUGINS]/sqldrivers)

If you do not want Qt Creator to apply the modified environment to the program, click the "Projects" button on the left, and then below, where the "Runtime Environment", select "System Environment".

  • No, it did not help. Nothing has changed - Matty
  • Thank you, figured out. There is still a question, but not a critical one. Can I somehow ask sqlite not to create a database if there is none? Just display a "not found" error or do nothing at all. - Matty
  • @Matty, I don’t know the driver But you also have a check for the existence of an if(QFile::exists(path)) file if(QFile::exists(path)) . - maestro
  • So she passed ... Although probably this line was added a little later, when the driver has already managed to create an empty database. Ok, everything, no questions - Matty