QSqlTableModel only fetching table headers (with names) and no data from table QODBC
-
Hi,
Did you check whether QSqlTableModel returned any error ?
Also, in your
initDatabase
function, why returnlastError
only if everything goes correctly ? -
@SGaist I cannot check it right now, but I'll let You know in a couple hours.
I know that the initDatabase function return is illogical. I copied it from a colleague and will change it eventually.
First I wanted to know if there's a way to populate the QSqlTableModel. I would have less work, than with the other solution.I also tried QSqlQueryModel and the QSqlRelationalTableModel. The results were the same.
-
That's why I suggested to check the error state of the QSqlTableModel. If you can get values with a QSqlQuery then the model should also work.
-
The error is:
"Forward-only queries cannot be used in a data model"So if this: >link to a topic< is correct, I need to do this the longer way (using QStandardItemModel and populating it with an QSqlQuery)
-
Can you test with a QSqlQueryModel ?
-
What kind of database are you connection to ?
-
Ok, so not easily reproducible...
-
Hi,
I've got the same probleme with MS SQL server.
I want to use a QSqlQueryModel for getting datas in a QTableViewError
QSqlError("", "Forward-only queries cannot be used in a data model", "")Code I used :
QSqlQueryModel *model = new QSqlQueryModel(); QSqlQuery qry; qry.exec("Select * from villes"); model->setQuery (qry); listing = new QTableView; listing->setModel (model); qDebug()<<model->rowCount ();/ / this return 0 but Database get 13000 lines qDebug()<<model->lastError ();
Could you help me please ?
Best regards,
Jebi -
Hi,
I don't know anything about MS SQL, but I would start by changing 'qry.exec' to 'qry.prepare' or deleting the QSqlQuery like so:
QSqlQueryModel *model = new QSqlQueryModel(); QSqlQuery qry; qry.prepare("Select * from villes"); model->setQuery (qry); listing = new QTableView; listing->setModel (model); qDebug()<<model->rowCount ();/ / this return 0 but Database get 13000 lines qDebug()<<model->lastError ();
or just:
QSqlQueryModel *model = new QSqlQueryModel(); model->setQuery ("Select * from villes"); listing = new QTableView; listing->setModel (model); qDebug()<<model->rowCount ();/ / this return 0 but Database get 13000 lines qDebug()<<model->lastError ();
-
If this doesn't help try:
http://stackoverflow.com/questions/3060916/connection-to-sql-server-with-qt
or the VoidRealms tutorials:
-
@michalos
thanks a lot for your fast answers.I tried your solutions but problem is the same.
I'm sure it's not a problem from connection to server because all my queries works.
In this case, I have the name of my columns, but no datas in QtableView
Here is the form :
.Best regards.
Jebi
-
Why not use a QSqlTableModel for the
villes
table ? -
I've uncovered the same issue with QSqlQueryModel using the Windows QODBC database engine connected to MS SQL Server, and have been do some digging. Hopefully this will help others experiencing this issue.
There are a couple of different things happening here.
First, QSqlQueryModel does not support forward only queries. If you try to use a forward only query,
QSqlQueryModel::lastError()
will return "Forward-only queries cannot be used in a data model".That seems clear, but does not explain the situation when the forward only is left in its default
false
state or explicitly set in code. During my exploration of the issue, I would notice that even though I calledQSqlQuery::setForwardOnly(false)
, a call toQSqlQuery::isForwardOnly()
made after the query was executed would show forward only set totrue
, something I did not understand.Then I read the Qt documentation for setForwardOnly:
Setting forward only to false is a suggestion to the database engine, which has the final say on whether a result set is forward only or scrollable. isForwardOnly() will always return the correct status of the result set.
The database engine has the final say whether or not forward only is used!
Why was the database engine setting forward only? Qt's SQL Database Drivers documentation gives part of the answer if you know what you are looking at.
ODBC Stored Procedure Support
With Microsoft SQL Server the result set returned by a stored procedure that uses the return statement, or returns multiple result sets, will be accessible only if you set the query's forward only mode to forward using QSqlQuery::setForwardOnly().
By observation, the QODBC database engine (in Qt 5.8) recognizes when more than one return set has resulted from the query, so it is automatically setting forward only to
true
.How are multiple result sets generated? I've uncovered a few ways.
- A query that has multiple select statements (e.g.
select * from table1; select * from table2
). - Stored Procedures In particular, MS SQL Server documentation has this to say:
SQL Server stored procedures have four mechanisms used to return data:
- Each SELECT statement in the procedure generates a result set.
- The procedure can return data through output parameters.
- A cursor output parameter can pass back a Transact-SQL server cursor.
- The procedure can have an integer return code.
The first item in Microsoft's list was the key for me. When
NOCOUNT
is OFF, Even a simple internal variable assignment using a select (e.g.select @user = 'fred'
) generated a return set. SettingNOCOUNT
to ON stops this behavior. From Microsoft's documentation on NOCOUNTSET NOCOUNT ON prevents the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. For stored procedures that contain several statements that do not return much actual data, or for procedures that contain Transact-SQL loops, setting SET NOCOUNT to ON can provide a significant performance boost, because network traffic is greatly reduced.
The Solution for me turned out to be two things:
- Add
SET NOCOUNT ON
to the top of my stored procedure so that only the select statement I cared about was returned - Instead of using
QSqlQueryModel
, manually extract the results from the query and build my ownQStandardItemModel
.
- A query that has multiple select statements (e.g.