PDA

View Full Version : Does 'QSqlQueryModel' have a bug?



nuntawat
16th March 2010, 11:52
Hello. Now I have a problem when using QSqlQueryModel or QSqlTableModel. I installed an open-source version of Qt 4.6.2 for VS2008 and Qt 1.4.4 add-in for VS2008 on WinXP. The VC++ compiler always throw the error message "error C2248: 'QSqlTableModel::setQuery' : cannot access protected member declared in class 'QSqlTableModel'" when I set a parameter in setQuery() function as below:


QSqlTableModel *model;

// assume that 'stock' is a table.
model->setQuery(tr("SELECT * FROM stock WHERE id = %1").arg(ui.searchComboBox->currentText()));

or


QSqlTableModel *model;

// assume that 'stock' is a table.
model->setQuery("SELECT * FROM stock WHERE id = 1");

But according to a Qt documentation (http://qt.nokia.com/doc/4.6/qsqlquerymodel.html), it said that user can pass a string into setQuery() function. So is it a bug and what should I do?

Thanks a lot!

schnitzel
16th March 2010, 17:14
according to QSqlTableModel::setQuery documentation:




void QSqlTableModel::setQuery ( const QSqlQuery & query ) [protected]
This function simply calls QSqlQueryModel::setQuery(query). You should normally not call it on a QSqlTableModel. Instead, use setTable(), setSort(), setFilter(), etc., to set up the query.

See also selectStatement().


try setFilter() on the QSqlTableModel, just like the documentation suggests or use the QSqlQueryModel.

nuntawat
16th March 2010, 17:41
according to QSqlTableModel::setQuery documentation:




try setFilter() on the QSqlTableModel, just like the documentation suggests or use the QSqlQueryModel.

Sorry, but acrtually I would like to query using either QSqlQueryModel or QSqlTableModel (depending on a situation) from more than one table. So I need to set up the query myself. Does anyone have the solution?

waynew
16th March 2010, 21:53
Did you #include <QSqlQueryModel> ? That would give you the same error if you did not.

nuntawat
16th March 2010, 23:33
Did you #include <QSqlQueryModel> ? That would give you the same error if you did not.

I think the only way to use setQuery() function is passing string directly; noth tr() and QString can't be passed into that function.

But now I have a problem because I would like to use the QSqlQueryModel to fetch the data with specific condition (WHERE clause) and then display, but I can't add it to the query string which must be passed directly as I told before, and furthermore there is no function like setFilter() as QSqlTableModel has.

I'm very appreciated if you or any one post a solution. Thanks!! :)

waynew
17th March 2010, 00:03
That is not true. You can do this (it works in my code):



QSqlQuery query;
query.prepare("SELECT * from table_name where column = ?");
query.addBindValue("value");
query.exec();
model->setQuery(query);

nuntawat
17th March 2010, 05:15
That is not true. You can do this (it works in my code):



QSqlQuery query;
query.prepare("SELECT * from table_name where column = ?");
query.addBindValue("value");
query.exec();
model->setQuery(query);


Thanks!!! I just knew that setQuery() didn't execute the query!!

wysota
17th March 2010, 12:58
I think the only way to use setQuery() function is passing string directly; noth tr() and QString can't be passed into that function.
Hmm? That's not true.


But now I have a problem because I would like to use the QSqlQueryModel to fetch the data with specific condition (WHERE clause) and then display, but I can't add it to the query string which must be passed directly as I told before, and furthermore there is no function like setFilter() as QSqlTableModel has.

The table model is for representing a single table, you can't query for data from more than one table using that. You can't use setQuery() on QSqlTableModel as this wouldn't make sense - what differs QSqlTableModel and QSqlQueryModel is the query itself. If you overrode that, the table model could not execute its query anymore, that's why it is protected in QSqlTableModel. setFilter() only sets the WHERE clause on the model's query, it will influence rows, not columns. Functionally the two models are alike with the only exception that the table model is able to insert new rows into the table.

ajg85
6th April 2010, 17:45
as wysota pointed out what you are attempting conflicts with documentation:


void QSqlTableModel::setQuery ( const QSqlQuery & query ) [protected]
This function simply calls QSqlQueryModel::setQuery(query). You should normally not call it on a QSqlTableModel. Instead, use setTable(), setSort(), setFilter(), etc., to set up the query.

See also selectStatement().

Not only does setQuery not accept a string it is protected which means unless you make your own class which inherits from QSqlTableModel and sets the query internally this will cause a compile error. Regardless the query needs to be a single table select statement I believe.

Calling setTable will fetch the column information and setup your SELECT and FROM clauses.
Calling setFilter will setup your WHERE clause with the predicates you specify.
Calling setSort will setup your ORDER BY clause with column and ascending or descending keyword.

The minimum required before calling select() to populate the data is setTable which if used alone will basically do SELECT * FROM tablename except it will explicitly select columns so the order is guaranteed.