Return a value from SQL Query Qt - sql

I am trying to return a value from SQL Query. When logging in, 'Type' is a value in the database, 1,2 or 3. username and password are QStrings in the code.
In my attempt, this returns the wrong value (just a 1)
int userrole = roleQry.exec("SELECT Type FROM [tss_people] WHERE Username=\'" + username + "' AND Password='" + password + "'");
qDebug() << userrole;

QSqlQuery::exec() returns a status, i.e. whether the query was successfully executed or not.
Results can be optained by iterating over the query
while(roleQry.next()) {
qDebug() << roleQry.value(0).toInt();
}

Related

SQLite error in QT - QSqlError("", "Parameter count mismatch", "")

I'm trying to simply count the amount of records that has a 'true' status.
this is the SQLite table structure:
CREATE TABLE Suppliers(ID INTEGER PRIMARY KEY AUTOINCREMENT,Name varchar(50),Number varchar(15),URL varchar(70),Status bool,ShippingCost integer)
I am then calling a query from QT as follows:
int SQLiteController::ActiveSupplierCount()
{
int count = 0;
QSqlQuery Query;
Query.prepare("SELECT *"
"FROM Suppliers"
"WHERE Status = (:Status)");
Query.bindValue(":Status", true);
Query.exec();
qDebug() << Query.lastError();
while(Query.next() == true)
{
count++;
}
qDebug() << count;
return count;
};
The last error returned here is "Parameter count mismatch"
and I cannot figure out why... There is only 1 parameter, and I assign to that 1 parameter.
Try to add some extra spaces after each line of your query like this
Query.prepare("SELECT * "
"FROM Suppliers "
"WHERE Status = (:Status)");

Sqlite Update query with SqliteModernCpp

I am using the SqliteModernCpp library. I have a data access object pattern, including the following function:
void movie_data_access_object::update_movie(movie to_update)
{
// connect to the database
sqlite::database db(this->connection_string);
// execute the query
std::string query = "UPDATE movies SET title = " + to_update.get_title() + " WHERE rowid = " + std::to_string(to_update.get_id());
db << query;
}
Essentially, I want to update the record in the database whose rowid (the PK) has the value that the object to_update has in its parameter (which is returned by get_id()).
This code yields an SQL logic error. What is the cause of this?
It turned out single quotes (') within the query string being created were missing. The line should be:
std::string query = "UPDATE movies SET title = '" + to_update.get_title() + "' WHERE rowid = " + std::to_string(to_update.get_id());
Since there is no UPDATE example in the official docs on github, This is how UPDATE queries should be implemented with prepared statements and binding
#define MODERN_SQLITE_STD_OPTIONAL_SUPPORT
#include "sqlite_modern_cpp.h"
struct Book {
int id;
string title;
string details;
Book(int id_, string title_, string details_):
id(std::move(id_)),
title(std::move(title_)),
details(std::move(details_)) {}
}
int main() {
Book book = Book(0, "foo", "bar")
sqlite::database db("stackoverflow.db");
// Assuming there is a record in table `book` that we want to `update`
db <<
" UPDATE book SET "
" title = ?, "
" details = ? "
" WHERE id = ?; "
<< book.title
<< book.details
<< book.id;
return 0;
}

MSSQL Returns Different result in SSMS and Node JS script

I have a SQL query to return customer's transaction header using customer's card_number. The SQL query will return a column called audit_number. The problem is the when i execute the SQL query using SSMS software, the query returns proper results, but when i execute the query on my Node JS script some of the audit_number are wrong.
The audit_number should be 14111990000015953 and 14111990000015952 but when i execute the query in my NODE JS script both audit_number become 14111990000015952.
Here is my sql query
SELECT
h.Log_trxdate AS trx_date,
CAST(h.log_audit AS varchar) AS audit_number,
h.currency_code
FROM log_header h
WHERE h.id_code = '10000010055919' --card_number
Here is my Node JS Script
var querySQL = " SELECT ";
querySQL = querySQL + " h.Log_trxdate AS trx_date, ";
querySQL = querySQL + " CAST(h.log_audit AS varchar) AS audit_number, ";
querySQL = querySQL + " FROM log_header h ";
querySQL = querySQL + " WHERE h.id_code = 10000010055919 ";
sql.connect(config, function (err) {
var req = new sql.Request();
req.query(querySQL, function (err, result) {
console.log(result);
});
});
You need to change your datatype number to varchar/text since in javascript if the number length is more than 16 digits then it will give you some random number.
So to get exact result you should change your Datatype from number to string.
For example if you check number
Number(1111111111111111)//16 digits
Result is 1111111111111111
But if you put Number(11111111111111111)//17 digits
then result will be 11111111111111112 something

PetaPoco db.SingleOrDefault<T> passing in where name as well as value

I am trying to write a generic method to call DB records.
All works except to make the method useful I need to passing the WHERE name value too...as well as the value to match.
Something like this...
T values = db.SingleOrDefault<T>("WHERE " + name + " = #0", value);
This works but its a bit of a clunk!
string sql = "WHERE " + name + " = #0";
T values = db.SingleOrDefault<T>(sql, value);
Can this be done with different syntax?
Thanks
You can create an extension method to hide the syntax if that bothers you
public static T SingleOrDefaultWithWhere<T>(this PetaPoco.Database db, string name, object value) {
string sql = "WHERE " + name + " = #0";
return db.SingleOrDefault<T>(sql, value);
}
And then just call
T values = db.SingleOrDefaultWithWhere<T>(name, value);

query.next() returning false

I have used the query.next() function inside my code, but its returning false.
I even checked in the database, there are 4 records present. But the code shows only one.
However if i use query.next() before the code of query.valid() then it doesn't show any record
Please help
qDebug() << "entering payment: get all the unchecked invoices for user: " + user;
QStringList tmp;
QSqlQuery query(m_storageUserManager->database());
m_storageUserManager->dumpTable(m_invoiceInfoTable);
m_storageUserManager->dumpTable(m_invoiceUserTable);
qDebug()<<"THE NAME OF THE INVOICE USER TABLE_----=-----------------"<<m_invoiceInfoTable;
qDebug()<<"THE NAME OF THE INVOICE USER TABLE_----=-----------------"<<m_invoiceUserTable;
query.prepare("SELECT invoice FROM "+ m_invoiceInfoTable +" WHERE invoice = (SELECT
invoice FROM "+ m_invoiceUserTable +" WHERE user=:user)");
// query.prepare("SELECT invoice FROM " + m_invoiceInfoTable + ","+ m_invoiceUserTable +" WHERE " + m_invoiceInfoTable + ".user = " + m_invoiceUserTable + ".:user");
query.bindValue(":user", user);
query.exec();
query.first();
qDebug()<<"Unchecked invoices done!!! " ;
if(query.isValid()) {
do {
tmp.append(query.value(0).toString()); //as the value returned by value() is a QVariant so we need to change it to String.
} while(query.next());
} else
tmp.append("No Unchecked invoice in the database");
return tmp;
To check if the query was successful you should test the return value of either QSqlQuery::exec() or QSqlQuery::isActive() before trying to call first/next/last (when you pass the query string to the constructor of QSqlQuery, the query is already executed, so, you need to use QSqlQuery::isActive()).
first(), next() and last() return true if they positioned the query on a valid record, you don't have to test isValid() separately. Since first() is a positioning function too, you can read the value without calling next() directly after, unless you want to skip the first record.
Since you may want to add fields from the the "invoice-info" table to your query, I kept the subquery (with IN instead of = as Mat already answered in the comment).
query.prepare(QString("SELECT invoice FROM %1 WHERE invoice "
"IN (SELECT invoice FROM %2 WHERE user=:user)")
.arg(m_invoiceInfoTable, m_invoiceUserTable));
/*
// Or with an inner join
query.prepare(QString("SELECT %1.invoice FROM %1 "
"INNER JOIN %2 ON %1.invoice = %2.invoice "
"WHERE user=:user").arg(m_invoiceInfoTable, m_invoiceUserTable));*/
query.bindValue(":user", user);
if (!query.exec()) {
tmp.append("Query error: %1" + query.lastError().text());
} else if (!query.first()) {
tmp.append("No Unchecked invoice in the database");
} else {
do {
tmp.append(query.value(0).toString());
} while(query.next());
}
Try
query.prepare("SELECT invoice FROM " + m_invoiceInfoTable + " WHERE user=:user");