Qt SQLite can't perform Select querys - c++

I know many questions were asked around the issue I have, I spent along time trying to implement all kinds of solutions but didn't help.
I am trying to read a .db file using Qt SQLite platform.
windows 8 Qt 5.3.2
Opening the db file in DB browser for SQLite and executing my simple query succeeds:
SELECT Name FROM Person ORDER BY Name
and there is a list of 10 rows at the output.
I would like to do it throw Qt. my code:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("C:\mydb.db");
if(db.open())
{
QSqlQuery qry(db);
if(qry.exec("SELECT Name FROM Person ORDER BY Name"))
{
while(qry.next())
{
//some code
}
}
QSqlError e;
QString s,d;
e = qry.lastError();
s = e.databaseText();
d = e.driverText();
}
this code falls, the qry.exec command returns false, and last error is "no such table; person"
Running the command: QStringList tables = db.tables(QSql::AllTables);
after the Data Base is open shows that there is one table in Data Base called: sqlite_master.
trying to replace the query within the exec command with the query: "SELECT tbl_name FROM sqlite_master WHERE type = 'table'"
as says at: http://www.sqlite.org/faq.html#q7
causes the exec command to return true but qry.next() returns false already from the first iteration, although I have 5 tables in my data base.
I would be great full to how ever can me with my problem!
thanks!!!

You should specify the path to the database file correctly. Instead of C:\mydb.db you should use C:\\mydb.db or C:/mydb.db.
That's because the compiler uses \ as an escape character in strings (for things like \t, \n or \r). so \\ is actually turned into \.

Related

Qt Sql not able to bind variables to QSqlQuery prepare Statement

I am trying to fetch some records from MySQL database by using a prepared statement by using QSqlQuery as:
QString username=ui->textEdit_password->toPlainText();
QString password=ui->textEdit_password->toPlainText();
QSqlQuery query;
query.prepare("SELECT * FROM login_access WHERE username=? AND password=?");
query.addBindValue(username);
query.addBindValue(password);
query.exec();`
When i run :
std::string q_str1=query.executedQuery().toUtf8().constData();
std::cout<<"Query : "<<q_str1<<"\n";
It outputs : Query : SELECT * FROM login_access WHERE username=? AND password=? where the "?" has not been replaced and the query returns nothing since the "?" character is compared to the database records.
On running the query: SELECT * FROM login_access, the query returns all the database records in the login_access table.
I have also tried replacing the "?" with placeholders ":uname",":pass" and changed query.addBindValue(username); to query.bindValue(":uname",username);, and done same with password field.
I am running QtCreator 4.4.1
Thanks.
Use query.bindValue( ...) because this sets the placeholder value.
I tested executedQuery() on one of my SQL statements with placeholders and it returned a string with just the placeholders, not the values. The documentation does say that in most cases it the same string as lastQuery().
http://doc.qt.io/qt-5/qsqlquery.html#executedQuery
You have confirmed that your SQL statement without the where clause works so the next stage is to check you are binding what you think you are binding. To do this use boundValue(const QString placeholder) to find out if the placehold value is being bound.
It might also be useful to check the query has run OK.
So, after your query.exec you should put the following (assuming these are your placeholders) just to check these things:
qDebug() << query.lasterError();
qDebug() << query.boundValue(":uname");
qDebug() << query.boundValue(":pass");

how to insert variable's value in SQlite Database in Qt cpp

i am using Qt and i have written c++ code,i have already connected with sqlite database.i want to insert name in database
std::string name="Hello";
qry.prepare( "INSERT INTO s_no (Name,Status) VALUES ('name','1' )");
if( !qry.exec() )
qDebug() << qry.lastError();
else
qDebug( "Inserted!" );
but in db i am finding name only , not hello;
please help me..thank you so much in advance
C++ and SQL are two different programming languages, and execute in different environments. This means that C++ objects are not visible in SQL.
In theory, it would be possible to construct the string containing the SQL command so that the value of the name variable is inserted directly into it:
qry.prepare("INSERT INTO s_no (Name,Status) VALUES('" + name + "', '1')"); // don't do this
However, this will blow up if the name contains a quote. Escaping quotes would be possible with additional code, but a better way of getting variable values into an SQL query is to use parameters:
qry.prepare("INSERT INTO s_no (Name,Status) VALUES(?, '1')");
qry.bindValue(0, name);
(This is the only sensible way of using blob values in a query.)
Try making name a QString. You can change std::string to QString by using: QString name2 = QString::fromStdString(name);. Don't forget to include: #include <QString>.

App connection with Sqlite in my app developed in qt

In my app in QT5 I have this code
QString sql = "Select * from table";
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./au.sqlite");
db.open();
QSqlQuery query(sql);
query.exec();
But when I get the results only get one result, the select query only give me one result and I don't know how fix this. If I add query.next() in a while loop I only get one iteration.
There is a bool function that returns true if the query succeeded. Looking back to the docs:
Successfully executed SQL statements set the query's state to active so that isActive() returns true. Otherwise the query's state is set to inactive.
This is the way you can check the result. If it's false, then You should try to rewrite your sql query text so that functional sql words (such as SELECT, FROM and etc.) are in the upper case (the way it's shown in the docs) and try to execute the query once again.
Here's an example from the docs again:
QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
QString country = query.value(0).toString();
doSomething(country);
}
You might check sqlbrowser example that is included with Qt5 distribution. Run your query there on your db.

Qt/SQL - Get column type and name from table without record

Using Qt, I have to connect to a database and list column's types and names from a table. I have two constraints:
1 The database type must not be a problem (This has to work on PostgreSQL, SQL Server, MySQL, ...)
2 When I looked on the internet, I found solutions that work but only if there are one or more reocrd into the table. And I have to get column's type and name with or without record into this database.
I searched a lot on the internet but I didn't find any solutions.
I am looking for an answer in Qt/C++ or using a query that can do that.
Thanks for help !
QSqlDriver::record() takes a table name and returns a QSqlRecord, from which you can fetch the fields using QSqlRecord::field().
So, given a QSqlDatabase db,
fetch the driver with db.driver(),
fetch the list of tables with db.tables(),
fetch the a QSqlRecord for each table from driver->record(tableName), and
fetch the number of fields with record.count() and the name and type with record.field(x)
According to the previous answers, I make the implementation as below.It can work well, hope it can help you.
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSLITE", "demo_conn"); //create a db connection
QString strDBPath = "db_path";
db.setDatabaseName(strDBPath); //set the db file
QSqlRecord record = db.record("table_name"); //get the record of the certain table
int n = record.count();
for(int i = 0; i < n; i++)
{
QString strField = record.fieldName(i);
}
}
QSqlDatabase::removeDatabase("demo_conn"); //remove the db connection
Getting column names and types is a database-specific operation. But you can have a single C++ function that will use the correct sql query according to the QSqlDriver you currently use:
QStringlist getColumnNames()
{
QString sql;
if (db.driverName.contains("QOCI", Qt::CaseInsensitive))
{
sql = ...
}
else if (db.driverName.contains("QPSQL", Qt::CaseInsensitive))
{
sql = ...
}
else
{
qCritical() << "unsupported db";
return QStringlist();
}
QSqlQuery res = db.exec(sql);
...
// getting names from db-specific sql query results
}
I don't know of any existing mechanism in Qt which allows that (though it might exist - maybe by using QSqlTableModel). If noone else knows of such a thing, I would just do the following:
Create data classes to store the information you require, e.g. a class TableInfo which stores a list of ColumnInfo objects which have a name and a type.
Create an interface e.g. ITableInfoReader which has a pure virtual TableInfo* retrieveTableInfo( const QString& tableName ) method.
Create one subclass of ITableInfoReader for every database you want to support. This allows doing queries which are only supported on one or a subset of all databases.
Create a TableInfoReaderFactory class which allows creation of the appropriate ITableInfoReader subclass dependent on the used database
This allows you to have your main code independent from the database, by using only the ITableInfoReader interface.
Example:
Input:
database: The QSqlDatabase which is used for executing queries
tableName: The name of the table to retrieve information about
ITableInfoReader* tableInfoReader =
_tableInfoReaderFactory.createTableReader( database );
QList< ColumnInfo* > columnInfos = tableInfoReader->retrieveTableInfo( tableName );
foreach( ColumnInfo* columnInfo, columnInfos )
{
qDebug() << columnInfo.name() << columnInfo.type();
}
I found the solution. You just have to call the record function from QSqlDatabase. You have an empty record but you can still read column types and names.

SQLite - How to use it at terminal level & C++ application?

i am new to sqlite and I just recently installed it. I am familar with mysql but I need to use sqlite as I am using it for a C++ application that I am going to create.
Question 1:
I type this at my command line terminal
root#ubuntu:/home/baoky/version1.2/Assignment 2# sqlite abeserver.db
then I saw this output
sqlite>
So i type .h and i see a list of help commands
But i wanna create a table
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /home/baoky/version1.2/Assignment 2/abeserver.db
1 temp /var/tmp/sqlite_hjT3FEefcAHRPhn
in my main database
How do i execute this sql command at terminal level
CREATE TABLE abe_account (
username TEXT,
name TEXT,
department TEXT,
password TEXT
);
Question 2:
How do I insert record into the table abe_account using C++
Question 3:
How do I retrieve records from table abe_account and assign it to a string using C++
Sorry I tried google around and search around stack overflow, I am still confused with the usage, if its mysql, it would be much simple for me.
Question 2:
Question 3:
Let me google it for you, friend: An Introduction To The SQLite C/C++ Interface.
If you are using the sqlite terminal, you can just type SQL there, and it will be executed.
A typical cycle of work from your C++ code will look something like this:
sqlite3 * db;//database
sqlite3_stmt * stmt;//sql statement
sqlite3_open( "database.db", & db );//opening database
sqlite3_prepare( db, "SELECT something FROM something else;", -1, &stmt, NULL );//preparing the statement
sqlite3_step( stmt );//executing the statement
while( sqlite3_column_text( stmt, 0 ) )
{
char * str = (char *) sqlite3_column_text( stmt, 0 );///reading the 1st column of the result
//do your stuff
sqlite3_step( stmt );//moving to the next row of the result
}
sqlite3_finalize(stmt);
sqlite3_close(db);
You can easily google the functions to learn about their arguments and what they do in-detail.
To create a new database, just connect to it:
$ sqlite3 your_database_file
This will create your database in the file your_database_file. If this file already exists, the command will open it.
Then you can execute CREATE TABLE or any other SQL.