In our sql lite terminal when we type
SELECT * FROM Measures
we get everything from measure in the database called OMBI.db.
But now we want to connect the database via QT C++ GUI development platform. To do this we used the following code:
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("/Desktop/project/src/OMBI.db");
bool db_ok = db.open();
qDebug() << db_ok;
QSqlQuery query;
//query.exec("SELECT * FROM Measures");
if(query.exec("SELECT * FROM Measures")){
while(query.next()){
qDebug() << query.value(0).toInt();
}
qDebug() << query.lastError().text();
qDebug() << "Inside First if Statement";
}
else
{
qDebug() << query.lastError().text();
}
Note that all our core code for the GUI project is placed under desktop/project/src and we've also placed OMBI.db database file inside there.
From other questions we were led to believe that if we have successfully opened the database, the line qDebug() << db_ok; would return true. Thinking that its been returning true, we thought our problem would be within the if statement where we query. But what we've found is that no matter what we set db.setDatabaseName("");, it will return true. What might our problem be? I am sure that we are not reading the database in correctly since if we type db.setDatabaseName("non_existent_random_file"); we still get true.
EDIT:
Also we keep getting the following error when we query:
"no such table: Measures Unable to execute statement"
Any ideas?
It will create the database if it doesn't exist. Probably your path is wrong. Shouldn't you have db.setDabaseName("/home/userName/Desktop/.....)?
Related
I am trying to delete a row from QSqlQueryModel as follows:
void MainWindow::deleteRecord()
{
int row_index= ui->tableView->currentIndex().row();
model->removeRow(row_index);
}
But it is not working.
I tried the following as well:
void MainWindow::deleteRecord()
{
int row_index= ui->tableView->currentIndex().row();
if(!db_manager->delete_record(QString::number(row_no))){
ui->appStatus->setText("Error: data deletion ...");
} else{
ui->appStatus->setText("Record deleted ...");
}
}
Where in db_manager, the function delete_recod(QString row_no) is:
bool DatabaseManager::delete_record(QString row_index)
{
QSqlQuery query;
query.prepare("DELETE FROM personal_Info WHERE ref_no = (:ref_no)");
query.bindValue(":ref_no",row_index);
if (!query.exec())
{
qDebug() << "Error" << query.lastError().text();
return false;
}
return true;
}
But also not working. In both attempts, the application doesn't crash and no SQLite errors.
What am I doing wrong and how can I fix it?
The first approach is failing because QSqlQueryModel does not implement removeRows. You're not checking its return value (bad! bad! bad!), which is false, meaning failure.
And how could it possibly implement a row removal function? Your SQL query can be literally anything, including result sets for which it does not make any sense to remove rows.
Instead, consider using a QSqlTableModel -- it or may not apply to your case, but given the form of your DELETE statement, I would say it does. (QSqlTableModel only shows the contets of one table / view).
The second approach is instead possibly working already. The fact you don't see your UI updated does not imply anything at all -- you should check the actual database contents to see if the DELETE statement actually worked and deleted something.
Now note that there's nothing coming from the database telling Qt to update its views. You need to set up that infrastructure. Modern databases support triggers and signalling systems (which are wrapped in Qt by QSqlDriver::notification), which can be used for this purposes. In other cases you msut manually trigger a refresh of your SQL model, for instance by calling QSqlTableModel::select().
As stated in the title, I have written code for QT to connect to a sqlite database.
bool FilterData::initDatabase(){
QDir d;
_db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE"));
_db->setDatabaseName("OMBI.db");
return _db->open();
}
void FilterData::loadFromDB(){
if(initDatabase()){
//set up the query
QSqlQuery query(*_db);
//vectors for storing results from the query
QVector<QString>* measures = new QVector<QString>();
QVector<QString>* title = new QVector<QString>();
QVector<QString>* type = new QVector<QString>();
query.prepare("SELECT * FROM measures");
query.exec();
while (query.next()) {
measures->push_front(query.value(0).toString());
title->push_front(query.value(1).toString());
type->push_front(query.value(2).toString());
}
std::cout<<"Passed reading query results"<<std::endl;
std::cout<<measures->size()<<std::endl;
emit measuresReady(*measures, *title, *type);
}
}
The database connects and opens just fine, however on testing the result of query.first(),
query.next(), query.isValid(), query.isActive(), and query.isSelect() are all false. OMBI.db has been placed in the project folder for QT, as this is my first time working with QT I wasn't sure if this was correct protocol or not.
I've been trying to find a solution to this for far too long, and I have searched quite a bit, but to no avail. Hopefully some of you gurus can shed some light on what I'm doing wrong.
edit:
I've determined that exec() is failing and query.lastError() is reporting "No query unable to fetch row". I am now trying to determine what is causing the query to fail so miserably. I checked _db->lastError() but it was empty which I assume is a good thing.
I have given up on trying to configure the MYSQL driver for the Qt 5.0 library, I am going to use the only driver currently available to me - "QSQLITE".
I have been trying to get this working for quite some time and have tried everything mentioned in similar posts:
Select from SQLite with Qt
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName(SQL_SERVER);
db.setPort(SQL_PORT);
db.setDatabaseName(SQL_DATABASE);
db.setUserName(SQL_USER);
db.setPassword(SQL_PASS);
bool dbSuccess = db.open();
QList<QString> deviceNames;
QString deviceName;
qDebug() << db;
if(dbSuccess){
QSqlQuery query;
qWarning("We made it into the DB");
query.exec("SELECT device_name FROM tbl_device");
while (query.next() ){
qDebug() << query.value(1).toString();
// deviceNames.append(deviceName);
//qDebug() << "Test: "<< deviceName;
}
}
else if(!db.open()){
qWarning("Database failed to load!");
}
Where SQL_Server = 192.168.1.100
I get the following qDebug output from the application:
QSqlDatabase(driver=""QSQLITE"", database=""homelogic"", host=""hendrenserver"", port=3306, user=""homelogic"", open=true)
We made it into the DB
The output suggests that the database connection is valid, however if I change the servername to something completely false such as "xlkcjox" or other random keys - I get the same output. What am I missing here? I feel like this should be relatively easy.
Please advise!
When using the sqlite driver for qt, the database name is a file on your disc, regardless of the host name. This is how sqlite works. It needs no host just a filename.
I am revisiting this question to share a very helpful link that I came across today. I reached a solution using Qt 4.8.4 and QODBC driver. Due to a need to use QSerialPort and project bugs, I updated to 5.0.1 today. When working on rebuilding my ODBC plugin, I found this link: http://seppemagiels.com/blog/create-mysql-driver-qt5-windows.
Within 20 minutes I had what I originally wanted, the QMYSQL driver, working. I hope this helps others!
I am a beginner with Qt, so my question might be a bit basic.
My intention is to work with an ODBC database located in my hard drive. I have tried to open it with this code:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setHostName("");
db.setDatabaseName("c:\\database.mdb");
bool ok = db.open();
QSqlQuery query;
query.exec("SELECT name FROM results WHERE tag>10");
while (query.next()) {
QString name1 = query.value(0).toString();
qDebug() << name1;
}
Now, the problem is that the program can't find the database, failing at the db.open() line. I suspect that Qt can't open a database directly, but instead has to deal with an SQL server. Is this so? If that's the case, I'd be grateful if you could give me some clues on how to go ahead, particularly regarding host name (is it localhost?).
Also, I am not sure of whether the path to the file must be included in DatabaseName.
PS: I have no problem shifting to a different kind of database/server, e.g. MySQL. So if your solution requires this, I'd be happy with it!
Thanks in advance
D
Unless you specifically need a Jet/MS Access format database for something else you'd be better off going with SQLite. Qt has SQLite support built-in (QSQLITE driver) - you just point it at the database file and go. No need to setup ODBC data sources or anything.
According to the documentation, you should set the setDatabaseName to the ODBC datasource. You then configure the ODBC datasource to point to the appropriate file.
For future reference:
Just as Werne Strydom said, the argument of setDatabaseName is not the database file name, but the name of the ODBC datasource that points to your database. Therefore, you need to create an ODBC that points to your database.
The usual way to do this (in Windows) would be to go to Control Panel\System & security\Administrative tools\Data Sources (ODBC). But if you're in a 64-bit machine and want to work with a 32-bit driver, go instead to C:\windows\SysWOW64 and run odbcad32.exe
When you do this, a dialog opens (same dialog regardless of 64/32-bits). Here you create your ODBC, give it a name and link it to your actual database. In my case, as I am working with a local database, I used the "User DNS" tab.
Then, back in Qt, you put that ODBC name as argument for setDatabaseName. And it works! (Or it did for me...)
The new bit of code looks like:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setHostName("localhost");
db.setDatabaseName("MyDataSource");
bool ok = db.open();
QSqlQuery query;
query.exec("SELECT name FROM results WHERE tag>10");
while (query.next()) {
QString name1 = query.value(0).toString();
qDebug() << name1;
}
where "MyDataSource" is the name I gave to the ODCB.
I am using QT framework. Basically I am creating application for ARM devices.
Now I've created sample application using SQLite for DB work. Thing is that one is working in my desktop but when I cross compiled it for device and tried to execute it in my device Getting error.
So I logged some error messages. Finally i found that DB file was created successfully but unable to create table in device.
Is it because of out of memory issue?
Code :
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("songs.db");
if (!db.open()) {
QMessageBox::critical(0, qApp->tr("Cannot open database"),
qApp->tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
"Click Cancel to exit."), QMessageBox::Cancel);
//return false;
debugLog("#fileListThread::run()-> Unable to establish a database connection.."<<db.lastError(););
}
else
{
debugLog("#fileListThread::run()-> opened songs.db successfully..");
}
QSqlQuery query;
bool queryStatus = query.exec("create table songsList (id int primary key, "
"Song varchar(20), Artist varchar(20),Producer varchar(20))");
if(queryStatus)
{
debugLog("#fileListThread::run()-> created table in songs DB successfully..");
}
else
{
debugLog("#fileListThread::run()-> failed to create table in songs DB.."<<query.lastError(););
}
Okay! One more quick question-> Is it possible to create DB file and executing queries inside in embeedded devices. In my device available free memory is 9MB.
Thanks,
Vishnu
I think you should use
CREATE TABLE IF NOT EXISTS songsList
sql statement rather than
create table songsList
Otherwise once the table is created , the second time you try to execute it, you may get an error.
Other than that I don't see a problem but who knows... I hope this helps.