Results 1 to 5 of 5

Thread: QSqlQuery works with composed QString, but not with bound values

  1. #1
    Join Date
    Aug 2013
    Posts
    32
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QSqlQuery works with composed QString, but not with bound values

    Hello.

    I have subclassed QSqlQueryModel. While reimplementing setData() I created a method which uses a QSqlQuery with some bound values to update the relevant row in the database.

    Qt Code:
    1. bool EditableSqlModel::setFirstName(int table, int id, const QString &firstName)
    2. {
    3. QSqlQuery query;
    4. query.prepare("UPDATE :table SET desc = :string WHERE id = :id;");
    5.  
    6. QString table_str;
    7. switch(table) {
    8. case 1:
    9. table_str = "presupuestados_cascos_y_accesorios";
    10. break;
    11. case 2:
    12. table_str = "presupuestados_complementos";
    13. break;
    14. case 3:
    15. table_str = "presupuestados_puertas_y_cajones";
    16. break;
    17. case 4:
    18. table_str = "presupuestados_electrodomesticos";
    19. break;
    20. default:
    21. return false;
    22. }
    23.  
    24. query.bindValue(":table", table_str);
    25. query.bindValue(":string", firstName);
    26. query.bindValue(":id", id);
    27.  
    28. if(query.exec())
    29. {
    30. return true;
    31. }
    32. else
    33. {
    34. qDebug() << Q_FUNC_INFO << query.lastQuery();
    35. qDebug() << Q_FUNC_INFO << query.lastError();
    36. qDebug() << Q_FUNC_INFO << query.boundValues();
    37. return false;
    38. }
    39. }
    To copy to clipboard, switch view to plain text mode 

    This, outputs:

    Qt Code:
    1. bool EditableSqlModel::setFirstName(int, int, const QString&) "UPDATE :table SET desc = :string WHERE id = :id;"
    2. bool EditableSqlModel::setFirstName(int, int, const QString&) QSqlError(-1, "Parameter count mismatch", "")
    3. bool EditableSqlModel::setFirstName(int, int, const QString&) QMap((":id", QVariant(int, 2) ) ( ":string" , QVariant(QString, "3719000000, PUERTA ESP., 117.96") ) ( ":table" , QVariant(QString, "presupuestados_puertas_y_cajones") ) )
    To copy to clipboard, switch view to plain text mode 

    But, if I use this instead, it just works!

    Qt Code:
    1. bool EditableSqlModel::setFirstName(int table, int id, const QString &firstName)
    2. {
    3. QSqlQuery query;
    4. //query.prepare("UPDATE :table SET desc = :string WHERE id = :id;");
    5.  
    6. QString table_str;
    7. switch(table) {
    8. case 1:
    9. table_str = "presupuestados_cascos_y_accesorios";
    10. break;
    11. case 2:
    12. table_str = "presupuestados_complementos";
    13. break;
    14. case 3:
    15. table_str = "presupuestados_puertas_y_cajones";
    16. break;
    17. case 4:
    18. table_str = "presupuestados_electrodomesticos";
    19. break;
    20. default:
    21. return false;
    22. }
    23.  
    24. /* query.bindValue(":table", table_str);
    25.   query.bindValue(":string", firstName);
    26.   query.bindValue(":id", id);
    27. */
    28. if(query.exec(QString("update %1 set desc = '%2' where id = %3")
    29. .arg(table_str)
    30. .arg(firstName)
    31. .arg(id)))
    32. {
    33. return true;
    34. }
    35. else
    36. {
    37. qDebug() << Q_FUNC_INFO << query.lastQuery();
    38. qDebug() << Q_FUNC_INFO << query.lastError();
    39. qDebug() << Q_FUNC_INFO << query.boundValues();
    40. return false;
    41. }
    42. }
    To copy to clipboard, switch view to plain text mode 

    Noting that:

    1. The argument number, according to the debug output, is exactly the same than the number of placeholders
    2. The type of such arguments is the same in both cases
    3. The table is the same, and the database is always the default one


    Can someone enlighten me on why this is failing?

    Thank you.

  2. #2
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSqlQuery works with composed QString, but not with bound values

    What database ? Probably the name of the table must be given directly. This is not a feature of Qt but the database.

  3. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QSqlQuery works with composed QString, but not with bound values

    Bind variables in Sql can only be used to specify values used in the WHERE (and possibly GROUP BY) clauses. Bind variables cannot be used to change the fundamental structure of the query. Bind variables are not the same as literal string substitutions.

    If you find you need to run the same query over many identically structured tables then your database can probably be better designed.

  4. #4
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSqlQuery works with composed QString, but not with bound values

    Quote Originally Posted by ChrisW67 View Post
    Bind variables in Sql can only be used to specify values used in the WHERE (and possibly GROUP BY) clauses. Bind variables cannot be used to change the fundamental structure of the query. Bind variables are not the same as literal string substitutions.
    False. You can bind most values except for the names of tables, functions etc. This is working
    Qt Code:
    1. query.prepare("UPDATE m_table SET first_col=:new_value WHERE test_col BETWEEN :min_value AND :max_value");
    2. query.bindValue(":new_value",123);
    3. query.bindValue(":min_value",10);
    4. query.bindValue(":max_value",19);
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Aug 2013
    Posts
    32
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QSqlQuery works with composed QString, but not with bound values

    I see. I just assumed that bindValue() would do a regular string substitution.

    Anyway, as suggested, I ended using a different approach here, both at db level as well as conceptually at model/view level.

    To sum it up, bindValue() doesn't work when it comes to substitute table names, right?

    Thank you for the answers, and forgive me for replying so late. I guess I really need to check my profile settings and see why the notification didn't arrive

Similar Threads

  1. Replies: 14
    Last Post: 16th May 2017, 03:51
  2. Replies: 1
    Last Post: 8th August 2011, 01:21
  3. Replies: 5
    Last Post: 13th May 2011, 00:02
  4. Replies: 1
    Last Post: 1st August 2010, 14:06
  5. Replies: 4
    Last Post: 1st February 2010, 14:21

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.