[Solved]QSqlQuery::prepare segmentation fault.



  • Hi everyone!
    I know that i'm doing something wrong, but in last 3 hours i can't figure out what exactly.
    While run method:
    @
    int uUserTask::GetId(QString key)
    {
    int retId = -1;
    QSqlQuery query;
    query.prepare(QString("select id from table where identifer='%1'").arg(key));
    QMutexLocker mxlock(&mutex);
    if(query.exec())
    {
    if(query.next())
    {
    retId = query.value(0).toInt();
    }
    }
    return retId;
    }@

    i got segmentation fault in qsql_mysql.cpp at body of prepare method(line 900):
    @
    r=mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length());
    @

    Segmentation fault happens not always, and i compared query strings in fault case with other case, they are identical. I think i'm using threads in a wrong way, but how?

    tools: QtSDK 1.2.1 Qt4.8.1
    Os: Kubuntu 12.04
    Db: MySQL 5.5.22

    Thank you!



  • I usually use "prepare" in conjunction with "bindValue".

    In your code why don't you use directly query.exec("....") ?



  • ...and why do you use mutex? Is you application multi-thread?



  • Try this instead:

    QSqlQuery query;
    query.exec(QString("select id from table where identifer='%1'").arg(key));

    If you still want to use prepare(). Try like this:

    QSqlQuery query;
    query.prepare("select id from table where identifer = ?");
    query.addBindValue(key, QSql::Out);



  • In a multi-thread application I call the following code fore every thread:
    @
    db = new QSqlDatabase();
    m_nomeDb = QString::number(qrand());
    *db = QSqlDatabase::cloneDatabase(QSqlDatabase::database(), m_nomeDb);
    db->open();
    @

    and for every query in the same thread:
    @
    QSqlQuery query(*db);
    query.exec("select .... bla bla bla ...");
    ...
    query.next();
    ...
    ...
    @





  • Thank you for replies!!!
    As shown by Lukas Geyer "A connection can only be used from within the thread that created it. ..."
    So i think solution of Luca prefered :).

    But now, i changed code like
    @query.exec(QString(“select id from table where identifer=’%1’”).arg(key));@
    and not get segmentation fault for now.

    Thank you again!



  • Luca what about memory leak
    @db = new QSqlDatabase();@
    when an object will deleted?

    Question 2:
    In this case(QSqlDatabase for every thread) Mutex are not needed?



  • [quote author="qxoz" date="1353576031"]Luca what about memory leak
    @db = new QSqlDatabase();@
    when an object will deleted?
    [/quote]

    I usually put that code in the parent object contructor and this:
    @
    db->close();
    delete db;
    QSqlDatabase::removeDatabase(m_nomeDb);
    @
    in the destruct.

    [quote author="qxoz" date="1353576031"]
    Question 2:
    In this case(QSqlDatabase for every thread) Mutex are not needed?
    [/quote]

    If you have two threads using two DB connections you don't need mutex to execute queries.



  • If you want to do as I wrote, you also need to make a DB connection in your main :
    @
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName(ip);
    db.setDatabaseName(db_name);
    db.setUserName(user);
    db.setPassword(pwd);

    db.open();
    

    @

    this way you create a main DB connection and you can use it in the main thread. Next you can "clone" the connections in your threads.



  • I changed my code as you said, and it works ok :). Thanks!



  • You are welcome...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.