PDA

View Full Version : QSqlQuery::isValid returns false



mismael85
12th March 2008, 20:36
hello,
i am accessing a ms access database and i have the folowing problem.

if(query->isSelect())
QMessageBox::warning(this, "title", "select true"); //always returns true
query->last();
if(query->isValid())
QMessageBox::warning(this, "title", "true"); // always return false

when i execute last() function it does not return the last record and the query position is set to an invalid position.
why when i execute the last() function it does not return the required record?
and why it points to an invalid position?
thank you

wysota
12th March 2008, 20:41
What does QSqlQuery::isActive() return?

mismael85
13th March 2008, 13:10
What does QSqlQuery::isActive() return?
i tried it before and after the QSqlQuery::last()
and it always returns true

wysota
13th March 2008, 13:59
Can you provide the whole block of code used to operate on the query?

mismael85
13th March 2008, 14:51
that is the code i use

#include "shamelareader.h"

shamelaReader::shamelaReader(QWidget *parent)
: QMainWindow(parent)
{
mainText = new QTextEdit(this);
setCentralWidget(mainText);

db= QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=c:\\book.mdb");
db.open();


createActions();
createToolBar();

query = new QSqlQuery();
query->exec("SELECT name FROM employee");
query->next();
mainText->setText(query->value(0).toString());

}
void shamelaReader::createActions()
{
nextAct = new QAction(tr("&Next"),this);
connect(nextAct, SIGNAL(triggered()), this, SLOT(next()));

prevAct = new QAction(tr("&previous"),this);
connect(prevAct, SIGNAL(triggered()), this, SLOT(prev()));

firstAct = new QAction(tr("first"), this);
connect(firstAct, SIGNAL(triggered()), this, SLOT(first()));

lastAct = new QAction(tr("last"), this);
connect(lastAct, SIGNAL(triggered()), this, SLOT(last()));


}

void shamelaReader::createToolBar()
{
toolBar = addToolBar(tr("Navigation"));
toolBar->addAction(firstAct);
toolBar->addAction(nextAct);
toolBar->addAction(prevAct);
toolBar->addAction(lastAct);
}

void shamelaReader::next()
{
query->next();
mainText->setText(query->value(0).toString());
}

void shamelaReader::prev()
{
query->previous();
mainText->setText(query->value(0).toString());
}

void shamelaReader::first()
{
query->first();
mainText->setText(query->value(0).toString());
}

void shamelaReader::last()
{

query->last();
if(query->isActive())
QMessageBox::warning(this, "title", "Active true");

if(query->isValid())
QMessageBox::warning(this, "title", "true");

mainText->setText(query->value(0).toString());
}

wysota
13th March 2008, 15:16
What does query->last() return? Maybe the driver only supports sequential access? Have you verified that?

mismael85
13th March 2008, 16:25
query->last()
return true

Maybe the driver only supports sequential access? Have you verified that?
how can i know that the driver does not support sequential access

wysota
13th March 2008, 16:33
if last() returns true, then it means the query has been positioned correctly.


if(query->last(){
QSqlRecord rec = query->record();
qDebug("%d", rec.count());
}

What does this output? Remember to have console enabled for your project or else you won't see anything.

mismael85
13th March 2008, 17:40
excuse me but i dont know how to enable the console.
i am using visual studio 2005.
i hope, i am not wasting your time.
but i believe if i want to learn some thing i must start my project directly as sayed in Qt documentation .but on the road there are missed things.
thank you

wysota
13th March 2008, 20:03
If you're using a commercial licence then access your project options using the integration plugin and it should be there somewhere. If not, run your application from within VS debugger and it should display the message. As an alternative, prepare a small qmake project and include a CONFIG+=console line in it.

mismael85
13th March 2008, 21:40
i made as you said and i get the following output:
1
QSqlQuery::value: not positioned on a valid record

wysota
13th March 2008, 22:04
How many records does the table hold?

mismael85
14th March 2008, 06:55
i tried it with two databases
one of them contains three records
and the other one contains 90 records.

wysota
14th March 2008, 08:35
Could you prepare a minimal compilable example reproducing the problem?

mismael85
14th March 2008, 20:51
here, it is the source code .
http://www.filesend.net/download.php?f=bcee2dc153ce9505cddf51c62f649b7c

please dont forget to put the sample database in the ( c:\ ) directory.
the database are contained in the Zip file and also the *.pro file.

mismael85
17th March 2008, 18:27
i tried the same code with Sqlite database and the program works fine.
but why does not it work with MS access?

wysota
17th March 2008, 18:40
As I (think I) already said, maybe Access only supports sequential access to data.

mismael85
17th March 2008, 20:08
do you mean that i can not deal with access databases with Qt?

wysota
17th March 2008, 21:05
No, I mean Access databases can't jump across the result set regardless if you use Qt or not. If you want to reach the last entry, you have to iterate each record one by one until you reach the end.

mismael85
18th March 2008, 14:32
but i have the program that deal with access database which is built using visual basic
and this program go through the database easy it make last , first, next and previous
and i want to rebuild this program using c++. it means that the database support non sequential access
as well as sequential.

wysota
18th March 2008, 16:39
Maybe it emulates last() using next(). It doesn't say anything about either the database or the ODBC driver that handles it.

haldrik
7th September 2008, 01:00
Hello, I have a similar problem with an sqlite3 database.

Queries work fine interactively, even queries work fine on the constructor, but on a slot give me this messages on console output:

QSqlQuery::value: not positioned on a valid record
QSqlQuery::value: not positioned on a valid record
QSqlQuery::value: not positioned on a valid record
QSqlQuery::value: not positioned on a valid record
QSqlQuery::value: not positioned on a valid record

I think each message is one for each field in the query string.

The query is executed and the values are retrived, I can use this values without problems, but this messages bothers me, and dirty my console output.

here the implementation of the slot:


void ThirdParties::setLoans(QString id)
{
qDebug() << id;
QSqlQuery queryLoans;
queryLoans.prepare("SELECT loan_id, date, value, quotas, cancel_quotas, loan_type FROM tblLOANS WHERE thirdparty_id=:id");
queryLoans.bindValue(":id", id);
if (!queryLoans.exec())
QMessageBox::warning(this, tr("Error en la consulta"), queryLoans.lastError().text());
loanIdComboBox->clear();
dateEdit->clear();
valueLineEdit->clear();
quotasLineEdit->clear();
cancelQuotasSpinBox->clear();

while (queryLoans.next())
{
qDebug() << queryLoans.value(0).toString();
loanIdComboBox->addItem(queryLoans.value(0).toString());
}
queryLoans.first();
dateEdit->setDate(queryLoans.value(1).toDate());
valueLineEdit->setText(queryLoans.value(2).toString());
quotasLineEdit->setText(queryLoans.value(3).toString());
loanTypeComboBox->setCurrentIndex(loanTypeComboBox->findText(queryLoans.value(5).toString()));
cancelQuotasSpinBox->setValue(queryLoans.value(4).toInt());
}

jacek
7th September 2008, 16:02
Do the errors disappear when you comment out lines #20--#25?

haldrik
7th September 2008, 18:00
Don't dessapear. Even I commented all lines exept the declaration, prepare-bindValue and executed lines of the query, the message still appear.

I repeat, this message appear only in this slot, on the constructor don't appear.

haldrik
7th September 2008, 23:43
Hello. Now I solved my problem.

The problem is using multiple connections (QObject::connect), the slot avobe call other signal i.e:



connect(idComboBox, SIGNAL(currentIndexChanged(QString)),
this, SLOT(setLoans(QString)));

connect(loanIdComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(setLoanValues(int)));


loanIdComboBox->clear(); call currentIndexChanged, on that connection I have the same query and for this behavior was the error.

I correct this behavior using at begin of slot loanIdComboBox->blockSignals(true) and then on final of slot loanIdComboBox->blockSignals(false).

DBG is a great help.