Connecting to Azure SQL Server with Qt on Linux - c++

I am trying to connect to a Azure SQL Server database with Qt on Linux but I have not could make it. I tried some like this: Connection to SQL Server with qt but the connection is never opened.
My code is so simple:
QString connectionTemplate = "DRIVER={SQL SERVER};SERVER=%1;DATABASE=%2;";
QString connectionString = connectionTemplate.arg("tcp:my-database.database.windows.net,1433").arg("my-database");
for(int i = 0; i < QSqlDatabase::drivers().size(); i++) {
qDebug() << QSqlDatabase::drivers().at(i);
}
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName(connectionString);
db.setUserName("user#my-database");
db.setPassword("My password");
//db.setConnectOptions("Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;");
bool ok = false;
try {
ok = db.open();
} catch(QException ex) {
qDebug() << ex.what();
}
qDebug("%s=%d", "conexión abierta", ok);
QSqlQueryModel *model = new QSqlQueryModel;
QString query = "SELECT 1 AS test_col";
model->setQuery(query, db);
db.close();
I already have the QODB and QODBC3 drivers so I don't know why I am unable to make the connection.
Is some related to driver, Qt, Azure or similar?

This is what I am doing and it works perfect for me:
Note: connName is the connection name on which I am opening the database.
QString connectionString = "Driver={ODBC Driver 13 for SQL Server};"
"Server=tcp:xxx.database.windows.net,1433;"
"Database=ABC;"
"Uid=aaa#xxx;"
"Pwd=***;"
"Encrypt=yes;"
"TrustServerCertificate=no;"
"Connection Timeout=30;";
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", connName);
db.setDatabaseName(connectionString);
if (db.open())
{
return true;
}
else
{
QString error = db.lastError().text();
return false;
}

Related

QT SQLITE Database wont open

I am having an extremely annoying problem and it doesn't make sense to me whats wrong. I am creating a multiple form ATM app but for some reason my DB is saying its open in the app but in the output it is throwing the error: QSqlQuery::exec: database not open
Here is the mainmenu.cpp file where I create the first instance of the DB
mainMenu::mainMenu(QWidget *parent) :QMainWindow(parent),ui(newUi::mainMenu)
{
ui->setupUi(this);
atmDB = QSqlDatabase::addDatabase("QSQLITE","myConnection");
atmDB.setDatabaseName(Path_to_DB);
QFileInfo checkFile(Path_to_DB);
}
Here in the login.cpp file it displays on the screen "Database connected"
login::login(QWidget *parent) :QDialog(parent),ui(new Ui::login)
{
ui->setupUi(this);
QSqlDatabase logindb;
logindb = QSqlDatabase::database("myConnection",true);
bool x = logindb.open();
if(!x){
ui->loginStatusL->setText("No connection to log-in database!");
}
else
ui->loginStatusL->setText("Database connected!");
}
But when the user pushes the button to login it it throws the SqlQuery error,
void login::on_loginLoginB_clicked()
{
QSqlDatabase loginB;
loginB = QSqlDatabase::database("myConnection",true); //open database
QString email, password;
email = ui->loginEmailbox->text();
password = ui->loginPassbox->text();
pubEmail = email;
if(!loginB.isOpen()){
ui->loginStatusL->setText("Connection to database lost");
return;
}
QSqlQuery qry;
if(qry.exec("SELECT * FROM userRecords WHERE email = '"+email+"' and password='"+password+"'")){
int count = 0;
while(qry.next()){
count++;
}
if(count==1){
userMenu usermenu;
atmDB.close();
usermenu.setModal(true);
usermenu.exec();
}
else
ui->loginStatusL->setText("Login failed. Email or password incorrect.");
}
}
I also have the same problem in my register.cpp file and it follows the same logic.
If you're looking to just know why wouldn't the QSqlQuery::exec() work, that's because you haven't told it anything about the database that it should run the query on.
The initialization should look more like:
QSqlDatabase loginB;
//code omitted...
QSqlQuery qry(loginDB); //Tell QSqlQuery which database to work with
//call qry.exe() here
I'd bet that it's the same problem in your register.cpp.

Handling QSqlDatabase connections

What is the correct way to handle connections for QSqlDatabase?
In my program I am doing it this way:
DatabaseConnector *databaseConnector = 0;
try
{
databaseConnector = new DatabaseConnector();
//Do stuff...
delete databaseConnector;
}
catch(QString e)
{
delete databaseConnector;
QMessageBox::information(this,"Error",e);
}
databaseConnector.h
#ifndef DATABASECONNECTOR_H
#define DATABASECONNECTOR_H
#include <QtSql>
class DatabaseConnector
{
public:
DatabaseConnector();
DatabaseConnector(QString hostname, QString database, QString user, QString password);
~DatabaseConnector();
private:
QSqlDatabase db;
};
#endif // DATABASECONNECTOR_H
databaseconnector.cpp
#include "databaseconnector.h"
#include <QString>
DatabaseConnector::DatabaseConnector()
{
QSettings settings;
db = QSqlDatabase::addDatabase("QIBASE");
db.setHostName(settings.value("db/host").toString());
db.setDatabaseName(settings.value("db/name").toString());
db.setUserName(settings.value("db/user").toString());
db.setPassword(settings.value("db/pass").toString());
if(!db.open())
{
QString databaseConnectionError = db.lastError().text();
throw databaseConnectionError;
}
}
DatabaseConnector::DatabaseConnector(QString hostname, QString database, QString user, QString password)
{
db = QSqlDatabase::addDatabase("QIBASE");
db.setHostName(hostname);
db.setDatabaseName(database);
db.setUserName(user);
db.setPassword(password);
if(!db.open())
{
QString databaseConnectionError = db.lastError().text();
throw databaseConnectionError;
}
}
DatabaseConnector::~DatabaseConnector()
{
db.close();
}
I'm getting error even if I use QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
Normally you don’t need to open the database connection more than once within your application.
When adding a database, you can name the connection :
QSqlDatabase::addDatabase( "QIBASE", "MyDBConnectionName" );
You can use the name to query for the connection :
if( QSqlDatabase::contains( "MyDBConnectionName" ) )
{
QSqlDatabase db = QSqlDatabase::database( "MyDBConnectionName" );
//Do stuff...
}
else
{
// connection not found, do something
}
Also notice that before calling QSqlDatabase::removeDatabase you should disconnect your database :
db.close();
QSqlDatabase::removeDatabase("MyDBConnectionName");
In order to add a new database, you need to give it a name. If you do not give a unique name, the default database is re-used. This is documented in the class reference.
Try:
db = QSqlDatabase::addDatabase("QIBASE", databaseName);
In main app:
QSqlDatabase db =QSqlDatabase::addDatabase( "QSQLITE");
in second app:
QSqlDatabase db2 =QSqlDatabase::database();

Can't execute mysql querys with QT

I'm trying to connect and execute a query with the QT framework, I can connect to the mysql db and I have tested the query and verified it works on the database. I think the mysql driver is correctly installed because I can connect and it doesn't throw any errors
void Login::on_loginButton_clicked()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setDatabaseName("TestBase");
db.setUserName("username");
db.setPassword("password");
if (!db.open()) {
QMessageBox::critical(0,"Database Error","Could not connect to the database, check your internet connection.");
}
QSqlQuery data("SELECT * FROM `TestBase`.`Users` WHERE `userName` = 'Afonso'");
//data.exec("SELECT * FROM `TestBase`.`Users` WHERE `userName` = 'Afonso'");
QMessageBox::information(NULL, "Query executed", "The query returned: " + data.exec());
}
I have also tried with
data.exec("insert query here");
data.next();
Nothing seems to work
I am trying to display the result of the query in a QMessageBox
QSqlQuery query(db);
query.prepare("SELECT * FROM `TestBase`.`Users` WHERE `userName` = :user_name");
query.bindValue(":user_name", "Afonso");
if (!query.exec())
{
qDebug() << query.lastError().text();
retrun;
}
while (query.next())
{
QVariant v = query.value(0);
}
I use pyqt but in general with a select query, I start to get data with
.first() rather than .exec() .exec_() in pyqt.
After that next() works just fine.

SQLite remove database error

I have widget which connects to database:
Widget::Widget(QWidget *parent)
{
QString databaseName = "name";
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(databaseName);
db.setHostName("localhost");
if(!db.open())
qDebug()<<"ret error";
}
Now I want to delete database connection after widget close (currently I get warnings like: QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection is still in use...). I' ve read some topics and tried to evaluate some solution from them but none works for me. My code:
void Widget::closeEvent(QCloseEvent *e)
{
QSqlDatabase db = QSqlDatabase::database();
QString connection = db.connectionName();
db.close();
QSqlDatabase::removeDatabase(connection);
qDebug()<<"error: "<<db.lastError().text();
}
Error I get is: Driver not loaded Driver not loaded
What is the correct way to do this?
Edit:
another method:
void Widget::someMethod()
{
QSqlDatabase db = QSqlDatabase::database();
QSqlQuery query(db);
query.exec("some query");
}
Try giving a connection name parameter(2nd parameter) in addDatabase() , that should solve your problem.
Here is the modified code you could try:
Widget::Widget(QWidget *parent)
{
QString databaseName = "name";
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "test_db_connection" );
db.setDatabaseName(databaseName);
db.setHostName("localhost");
if(!db.open())
qDebug()<<"ret error";
}
Here is a complete working code from my machine for sqlite database which you can use as reference:
local_db = QSqlDatabase::addDatabase("QSQLITE","localdb");
local_db.setDatabaseName("localdb.sqlite");
local_db_query = QSqlQuery(local_db);
local_db_query.prepare( "SELECT * FROM sample_table" );
local_db_query.exec();

Problem with SQLite & Qt

This is the code which has problem:
QMessageBox::information(this, "Connexion Open", "Connexion BD Ok!");
QSqlQuery req;
req.exec("SELECT * FROM reservation");
while(req.next()) {
float id = req.value(0).toFloat();
text2->setText(" "+QString::number(id)+" " );
The message "Connexion BD Ok!" appears perfectly.
How can I retrieve the result of the DB knowing that the DBMS(SGBD) is SQLite?
Thank You
It looks like you are already retrieving the id, so I'm guessing that your question is how you connect to a sqlite database in the first place with Qt. You typically specify the database when you are connecting. Something like:
QSqlDatabase db = QSqlDatabase::addDatabase(ntr("QSQLITE"));
QFileInfo dbPath(pathToDb, dbFileName);
db.setDatabaseName(dbPath.absoluteFilePath());
if (!db.open()) {
qDebug() << ntr("Could not open database:") << db.databaseName();
}
if (db.isOpenError()) {
QSqlError err = db.lastError();
qDebug() << ntr("Last error:") << err.text();
}