I am using Qt 5.4 and SQLite to to database operations, all other requests work, but this one doesn't seem to work and gives no error.
QSqlQuery query(Globals::db);
QString cmd = "Update VideoFile set isVisible = 0 WHERE Id =1;";
if(query.prepare(cmd))
qDebug("Prepare success..."); //<-- prints out
if (!query.exec()) {
qDebug("Error occurred querying.");
qDebug("%s.", qPrintable(Globals::db.lastError().text())); //<<-- prints out blank
}
Tried so far:
o) Database: exists!
o) Query Prepare() yields True
o) When executing the same Statement in SQLite Browser. Works!
i read about a problem here:, that some databases have a certain delay.
"Portability note: Some databases choose to delay preparing a query until it is executed the first time. In this case, preparing a syntactically wrong query succeeds, but every consecutive exec() will fail." But apparently, the query is not syntactically wrong.
Related
I'm creating a small c++ library to access MS SQL Server database using OLE DB (with cpp wrapper provided by atldbcli).
While SELECT or INSERT statements alone works fine I've encountered problem with SQL query like:
INSERT INTO testTable(col_int, col_str)
OUTPUT INSERTED.autincPK --output primary key value, required for further processing
VALUES (43, 'test str')
Produce error:
DB_E_ERRORSOCCURRED Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.
I'm unable to find more error info.
Query executes without any errors in database. Error message says 'No work was done' but new row is created in table (autocommit is enabled).
The relevant code looks like:
#include <atldbcli.h>
int execSQL(CSession *pSession, const std::string& sql)
{
CCommand<CDynamicAccessor, CRowset, CMultipleResults> command;
CDBPropSet rgPropertySet[1] = {};
rgPropertySet[0].SetGUID(DBPROPSET_ROWSET);
rgPropertySet[0].AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
rgPropertySet[0].AddProperty(DBPROP_CANFETCHBACKWARDS, true);
rgPropertySet[0].AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_DELETE | DBPROPVAL_UP_INSERT);
rgPropertySet[0].AddProperty(DBPROP_IMultipleResults, true);
}
HRESULT hr = command.Open(*pSession, sql.c_str(), rgPropertySet, &m_rowsAffected, DBGUID_DEFAULT, false, 1ul);
if (FAILED(hr)){
//error handling
}
return 0;
I searched SO and Google but didn't find much help on this question. It seems due to ODBC functions being called out out of order. But since I am using QSql that wraps ODBC, it is hard for me to track down the function. Please help...
I was able to connect to the sql server database
I tested a very simply query and still got the error. I don't think it's due to column binding.
I was able to run the query with sql server, so I think the sql query is ok.
The tools I am using:
VS c++ 2017, CMake, Qt 5.09.2, sql server 2017
Below are the error messages:
QODBCResult::exec: Unable to execute statement: "[Microsoft][ODBC Driver Manager] Function sequence error"
QSqlError("0", "QODBC3: Unable to execute statement", "[Microsoft][ODBC Driver Manager] Function sequence error")
Test coding:
This coding generate the error message above.
int main()
{
QSqlDatabase GUIInpDB = QSqlDatabase::addDatabase("QODBC", "MainSQLDB");
GUIInpDB.setConnectOptions();
QString inpSqlServer = "DESKTOP-085AEA8\\SQLEXPRESS";
QString dbName = "test";
QString connString = QString("Driver={ODBC Driver 13 for SQL Server};Server=%1;DATABASE=%2;Trusted_Connection=Yes;")
.arg(inpSqlServer).arg(dbName); //the argument replace the %1 and %2
GUIInpDB.setDatabaseName(connString);
QSqlDatabase db = QSqlDatabase::database("MainSQLDB");
if (!db.open())
{
qDebug() << "Connection for db not working";
return 1;
}
QSqlQuery query("SELECT * FROM TBL.tbl_test", db);
if (!query.exec())
qDebug() << query.lastError();
int num_of_rows = query.size();
getchar();
return 0;
}
I found this discussion on QtCenter that might help you, even if I am doubtful about why it fixed the issue
You migth try to use the QSqlQuery constructor that does not exec as mentionned
http://www.qtcentre.org/threads/18832-ODBC-function-sequence-error
Using C++ Qt framework and sql server 2008 I've been trying to insert a record into a table with an identity field and retrieve the identity value. Below is a simplified code sample which actually does do the insert but just doesn't retreive the identity. The identity returned from query.value(0) is an invalid QVariant.
QSqlQuery query(*pConn);
query.prepare("insert into [VH_MANUFACTURER] values ('sRRS test man code','RRS type','RRS logo file',1,'RRS SEO para','RRS description','RS');"
"select SCOPE_IDENTITY();");
if(query.exec())
{
if(query.next())
{
QVariant identity = query.value(0);
int id=identity.toInt();
}
}
I've tried using select ##identity instead of scope_identity with no improvement and also QSqlQuery .lastInsertId() which also returns an invalid QVariant, see below.
bool bFeature = pConn->driver()->hasFeature(QSqlDriver::LastInsertId);
QSqlQuery query(*pConn);
query.prepare("insert into [VH_MANUFACTURER] ([MFG_NAME],[MFG_TYPE],[MFG_LOGO],[MFG_ACTIVE],[MFG_SEO_CONTENT],[MFG_DESCRI],[MFG_CAPMANCODE]) values ('sRRS test man code','RRS type','RRS logo file',1,'RRS SEO para','RRS description','RS')");
if(query.exec())
{
QVariant id=query.lastInsertId();
}
hasFeature returns true, so the driver is supposed to support what I'm trying to do.
Just to test the sql , I ran the sql directly through Sql Server Management Studio and it inserts as expected and returns the identity value correctly.
Finally found a work around using OUTPUT clause in sql. I don't exactly know why the other methods I tried don't work. There is a sql server bug associated with this feature but that doesn't explain why it worked in ssms but not in c++ Qt code. The sample below show's the work around. Here's the reference I used to solve this.
bool bFeature = pConn->driver()->hasFeature(QSqlDriver::LastInsertId);
QSqlQuery query(*pConn);
query.prepare("insert into [VH_MANUFACTURER] ([MFG_NAME],[MFG_TYPE],[MFG_LOGO],[MFG_ACTIVE],[MFG_SEO_CONTENT],[MFG_DESCRI],[MFG_CAPMANCODE]) OUTPUT INSERTED.MFG_ID values ('sRRS test man code','RRS type','RRS logo file',1,'RRS SEO para','RRS description','RS')");
if(query.exec())
{
if(query.next())
{
QVariant id=query.value("MFG_ID");
}
}
I have what I think is a very simple case, but I don't understand why it fails.
Database used is sqlite3, linux platform. Qt 5.3.
I have this table: CREATE TABLE db_info (name TEXT, value TEXT);
Containing this data (output from sqlite3 client):
version|1
created|2015-01-16 11:06:12
Yes, it's very simple.
The purpose is to check if the DB is created with another version of the application. So I compare the version in the DB with a compiled constant in the code.
Thus, during startup, I do this (trimmed for brevity):
_db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", "mydb"));
_db->setDatabaseName(dbFile);
_db->open();
QSqlQuery query(*_db);
query.prepare("SELECT value FROM db_info WHERE name = 'version' AND value = :version");
query.bindValue(":version", DB_VERSION);
query.exec();
if(query.first())
// same version
else
// some other version
Not very complicated stuff...
Now to the specific problem:
_db->open() returns true
query.prepare() returns true
query.isSelect() returns true
query.exec() returns true
After exec():
query.isActive() returns true
query.size() returns -1
query.first() or query.next() returns false
What could be the problem?
According to the dox (http://doc.qt.io/qt-5/qsqlquery.html#first), first() returns false if the query is not active or it's not a select, so that can't be it.
But I guess, since size() returns -1 there definitely is something amiss somewhere...
I've tried adding some calls to lastError() but it's always empty. Both from query and from _db. It there some other means of getting some mesages from the database, or driver or some such?
I've also tried removing the WHERE clause. No difference.
Running the exact same query in the sqlite3 client works fine.
i have made a database in terminal by this command:
sqlite3 test.db
then i tried to make a table by using these codes:
ui->setupUi(this);
db1.setDatabaseName("test.db");
bool k=db1.open();
QSqlQuery q(db1);
q.prepare("CREATE TABLE by_code(id INT)");
q.exec();
qDebug()<<"isOpen: "<<k<<" Error:"<<q.lastError();
the output is :
isOpen: true Error: QSqlError(-1, "Unable to fetch row", "No query")
whats problem and how can i solve it?
Qt tried to get the result of the query, but a CREATE TABLE statement does not return a result.
This is not considered an actual error.
To check whether the query succeeded, check the return value of the exec function.