PDA

View Full Version : Why does QSqlQuery::prepare() return false?



NotANoob
20th April 2011, 16:26
Using: Qt3, Ubuntu 10.04, MySql 5.1

I'm attempting to use a prepared query to update a mysql database. The prepare() command is contained in a function (importBinaryStateData()) which is part of a very large application (too large to post here, I'll call the main application). For some mysterious reason, when used in the main application, prepare() returns false, and of course fails to prepare the query. If, however, I copy the function (importBinaryStateData()) out to a stand-alone test application (attached), it works exactly as it should. The main and test applications use the same database, driver, user, etc. Also, there are numerous queries throughout the main application that work, including prepared queries.

So I guess the question is this, is there any way to tell why prepare() might return false? I've tried lastError() and lastQuery(), all I get are nulls, zeros, and empty strings.

importBinaryStateData() (including prepare()) works here, but not as part of my main app.


#include <qapplication.h>
#include <qsqldriver.h>
#include <qsqldatabase.h>
#include <qsqlquery.h>
#include <qsqlcursor.h>
#include <qfile.h>

#define DRIVER "QMYSQL3" /* see the Qt SQL documentation for a list of available drivers */
#define DATABASE "Sequences" /* the name of your database */
#define USER "user" /* user name with appropriate rights */
#define PASSWORD "password" /* password for USER */
#define HOST "the-server" /* host on which the database is running */

QSqlDatabase* db;
bool importBinaryStateData( QString, QString, QString, QString, int );

int main( int argc, char ** argv )
{

QApplication a( argc, argv, FALSE );
db = QSqlDatabase::addDatabase( DRIVER );
db->setDatabaseName( DATABASE );
db->setUserName( USER );
db->setPassword( PASSWORD );
db->setHostName( HOST );
QString field = argv[1]; //"SM_Indx";
QString oldId = argv[2]; //"1";
QString newId = argv[3]; //"25";
QString path = argv[4]; // "/home/me/workarea/sequences/SI-003";
QString strSize = argv[5]; // 51497638
int size = strSize.toInt();
if (!importBinaryStateData(field, oldId, newId, path, size))
return 0;
else
return 1;
}

bool
importBinaryStateData( QString field, QString oldId, QString newId, QString path, int size )
{
qDebug("importBinaryStateData()");
bool success = true;
if (size > 0)
{
QFile file (path + "/" + "States_" + oldId + "_" + field + ".bin");
if (file.open(IO_ReadOnly))
{
QByteArray data = file.readAll();
if (data.size() == size)
{
if (db->open())
{
QSqlQuery q;
QString query = "UPDATE States SET " + field + " = ? WHERE State_ID = " + newId;
if (!q.prepare(query))
{
qDebug("prepare() failed!");
}

q.bindValue(0, data);
if (!q.exec())
{
qDebug("importBinaryActionData(): %s", q.lastError().text().ascii());
success = false;
}
db->close();
}
else
{
qDebug("importBinaryActionData(): Database not open by calling procedure.");
success = false;
}
}
else
{
qDebug("importBinaryActionData(): Could not read %s", file.name().ascii());
success = false;
}
file.close();
}
else
{
qDebug("importBinaryActionData(): Could not open %s", file.name().ascii());
success = false;
}
}
return success;
}

NotANoob
20th April 2011, 18:33
OK, figured it out ... sort of. I still don't know how to find out why QSqlQuery::prepare() returns false. However, through trial, error, and ultimately someone who knew what they were doing, I did manage to figure out why it returns false in my particular case.

The error is where I instantiate a QSqlQuery, q. This line should be


QSqlQuery q(db);

As it turns out, when the database is not specified, there is, or may be, a default database. In the case of my test app, there was only one database, and by default it was the right one (hence, q.prepare() worked). In my main application however, there were multiple databases, and the one I was intending to interact with, was not the default one (hence, q.prepare() did not work).

I still don't know the answer to my original question, but my immediate problem is fixed. Also, I might note that the offending line was lifted directly from the qt3 examples ... for whatever thats worth.

wysota
20th April 2011, 19:05
Prepare returns false because you're trying to run it without connecting to the database first.