Как нормально работать с QSqlDatabase
Заголовок изменён потому, что ответ на вопрос отражает почти все аспекты работы с QSqlDatabase для того чтобы сделать запрос к бд.
Есть метод:
QSqlDatabase::addDatabase(QSqlDriver *driver, const QString &connectionName) - сигнатура из подсказки qt (на картинке) в доке немного другая.

Проблема в том, что если я создаю базу без указания connectionName (как на рисунке выше), то query.exec:
- возвращает
код работы 1, - в противном случае (если я задаю имя данному соединению) возвращает
код работы 0, да еще и выдает ошибку на этапе исполнения
"QSqlQuery::prepare: database not open"
Получается, что я не могу задать имя подключению и соответственно удалить потом подключение, чтобы создать новое, тоже не могу.
Проблема именно в имени подключения, почему при его указании, не работает query.exec()?
PS: сам по себе запрос нормальный, я проверял на pgadmin, более того он работает, если не указывать имя подключения.
бд postgre\
Qt 5.15.3 (x86_64-little_endian-lp64 shared (dynamic) release
build; by GCC 11.3.0) on "xcb"
OS: Ubuntu 22.04.1 LTS [linux version 5.15.0-56-generic]
#include <iostream>
#include <QApplication>
#include <QSqlError>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlResult>
#include <QSqlRecord>
int main(int argc, char *argv[])
{
QSqlDatabase testDb;
testDb = QSqlDatabase::addDatabase("QPSQL");//testDb = QSqlDatabase::addDatabase("QPSQL","qwe");
testDb.setHostName(some_ip);
testDb.setPort(port);
testDb.setDatabaseName(name);
testDb.setUserName(some_user);
testDb.setPassword(some_pass);
bool ok = testDb.open();
std :: cout <<"\n----------------------\nconnection to gid DataBase is "<<ok;
QSqlQuery query;
query.prepare(some_select);
int a = query.exec();
QSqlError err = query.lastError();
//вывести ошибку
std :: cout <<"\n query.exec status (0 if bad) = "<<a<<"\n";
// query.finish();
}
Ответы (1 шт):
Итак, я разобрался:
объект базы данных
QSqlDatabase testDb("QPSQL","NAME1")надо создавать перед подключением к ней. Не делайте его глобальным каким-то или вне функции. Важно, чтобы он находился в отдельной области видимости и "исчезал" перед удалением(т.к. область видимости завершается).Создание объекта
QSqlDatabase testDbи заполнение егоHostNameи остальных полей должно быть внутри отдельной области видимости. Внутри неё же надо создавать и exec-ать query запрос.При создании
QSqlQuery queryиспользовать конструктор и передать туда бдQSqlQuery query(testDb).Удалять бд нужно вне этой области видимости
QSqlDatabase::removeDatabase("NAME1");Не забыть написать
query.finish();
void func(QString queryString)
{
{
QSqlDatabase testDB = QSqlDatabase::addDatabase("QPSQL","NAME1");//set db driver for PostgreSQL
testDB.setHostName("127.0.0.1"); //ip in string as "127.0.0.1"
testDB.setPort(5432); // port in int
testDB.setDatabaseName("my_db");//string
testDB.setUserName("my_name");//string
testDB.setPassword("qwerty12345");//pass in string
bool ok = testDB.open();
std :: cout << "testDB opened = " << ok << "\n";
QSqlQuery query(testDB);
int a = query.exec(queryString);
query.finish();
//----------------
QSqlError err = query.lastError();
std :: cout <<"\n query.exec of calc is done status (0 if bad) = "<<a<<"\n";
std :: cout << "\nERROR IS "<<err.text().toStdString();
}
QSqlDatabase::removeDatabase("NAME1");
}
Это самый локаничный и правильный пример по использованию QSqlDatabase, он позволит вам делать даже несколько подключений и с ними нормально работать.