QT Sql Error: Not positioned on a valid record - sql

I am unable to run Select query using QODBC (don't need QMysql). They throw QSqlQuery::value: not positioned on a valid record. However, other queries run fine.
There are other threads on the same issue on Stackoverflow. But none of them solves my problem. Here are a few
QSqlQuery not positioned on a valid record
Select query returns "value: not positioned on a valid record" in Qt
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName("Driver={MySQL ODBC 8.0 UNICODE Driver};DATABASE=dbname;");
db.setUserName("root");
db.setPassword("mysql");
if (!db.open()) {
qDebug() << db.lastError();
} else {
QSqlQuery query;
query.prepare("SELECT id, name FROM users where id=1;");
if (!query.exec())
{
qDebug() << "SQL error: "<< query.lastError().text() << endl;
}
query.first();
qDebug() << query.value("name").toString() ;
}
Help appreciated

Related

CDT inserter and extractor operator problem

this question is a continuing of Error on Constrained Delaunay Triangulation and Gabriel Triangulations
Trying to write a minimal example for that problem I planned insert the triangulation
in a file (std::ofstream) using the << operator of CDT without calling the CGAL::make_conforming_Delaunay_2(cdt); or CGAL::make_conforming_Gabriel_2(cdt),
knowing that until this point everything occured OK.
The triangulation was created without problems and before the exit of the aplication I saved the triangulation in a file using the << operator of CDT. The file was saved without error.
When I tried to read the file using the >> operator of CDT an exception was raised (inside the >> operator). The text of exception is:
CGAL ERROR: assertion violation!\nExpr: s == LEFT_TURN\nFile: C:\\dev\\CGAL-5.3.1\\include\\CGAL\\Triangulation_2.h\nLine: 919
The code I wrote:
int main()
{
CDT cdt;
std::ifstream ArqSuperficie("trian.dtr"); This file was created with << operator of CDT
if (ArqSuperficie.good() == false)
{
return 1;
}
try()
{
ArqSuperficie >> cdt;
}
catch(std::exception& e)
{
std::cerr << "ERROR: exception " << e.what() << std::endl;
}
return 0;
}
Why CDT cannot read a file created by itself, of a triangulation that was created by itself without errors?
Based on the message of the exception I canĀ“t have a clue of what is happening...
Thank you

How to output the concrete contents of a QsqlQuery before execution

For debuging prurpose I wouls like to print a sql query I am executing.
Here is my code:
QSqlQuery query;
query.prepare("INSERT INTO GeoAndEnergies VALUES(:smi,:chismi,:index,:rank,:comp,:met,:ba,:nha, :na, :gr, :gconv, :scfconv, :ener,:chemf,:prog,:ver,:cha,:mult,:sol,:geo, :freq, :enth, :free_e, :wei)");;
query.bindValue(":smi",QVariant(SMILES));
query.bindValue(":chismi",QVariant(ChiralSMILES));
query.bindValue(":index",QVariant(IndexCS));
query.bindValue(":rank",QVariant(Confrank));
query.bindValue(":comp",QVariant(Comptype));
query.bindValue(":met",QVariant(Method));
query.bindValue(":ba",QVariant(BASE));
query.bindValue(":nha",QVariant(NheavyAtom));
query.bindValue(":na",QVariant(NAtoms));
query.bindValue(":gr",QVariant(Grid));
query.bindValue(":gconv",QVariant(GeoConvergence));
query.bindValue(":scfconv",QVariant(SCFConvergence));
query.bindValue(":ener",QVariant(Energy));
query.bindValue(":chemf",QVariant(ChemicalFormula));
query.bindValue(":prog",QVariant(SOFTWARE));
query.bindValue(":ver",QVariant(VERSION));
query.bindValue(":cha",QVariant(Charge));
query.bindValue(":mult",QVariant(Multiplicity));
query.bindValue(":sol",QVariant(SOLVANT));
query.bindValue(":geo",QVariant(Geometry));
query.bindValue(":freq",QVariant(freq));
query.bindValue(":enth",QVariant(enthalpy));
query.bindValue(":free_e",QVariant(free_enthalpy));
query.bindValue(":wei",QVariant(weight));
if (!query.exec()){
std::cout << "Une erreur s'est produite. :(" << std::endl << q2c(query.lastError().text()) << std::endl;
}
return;
Thanks for tips.
query.executedQuery() will return the text of the last query that was successfully executed, with placeholder values replaced with concrete values. Hopefully, it'll also work if there was an error due to bad values, etc.
Note also that the explicit QVariant constructions are never necessary. For types that are handled by QVariant, the conversion will be done automatically. For custom types, there's no QVariant constructor available and the code won't compile anyway. You'd need to use QVariant::fromValue(xyz), where xyz has a custom type that has been Q_DECL_METATYPE'd in the header where the type is declared.
Your code could be rewritten as follows:
QSqlQuery query;
query.prepare("INSERT INTO GeoAndEnergies VALUES(:smi,:chismi,:index,:rank,:comp,:met,:ba,:nha, :na, :gr, :gconv, :scfconv,"
":ener,:chemf,:prog,:ver,:cha,:mult,:sol,:geo, :freq, :enth, :free_e, :wei)");
query.bindValue(":smi", SMILES);
query.bindValue(":chismi", ChiralSMILES);
query.bindValue(":index", IndexCS);
query.bindValue(":rank", Confrank);
query.bindValue(":comp", Comptype);
query.bindValue(":met", Method);
query.bindValue(":ba", BASE);
query.bindValue(":nha", NheavyAtom);
query.bindValue(":na", NAtoms);
query.bindValue(":gr", Grid);
query.bindValue(":gconv", GeoConvergence);
query.bindValue(":scfconv", SCFConvergence);
query.bindValue(":ener", Energy);
query.bindValue(":chemf", ChemicalFormula);
query.bindValue(":prog", SOFTWARE);
query.bindValue(":ver", VERSION);
query.bindValue(":cha", Charge);
query.bindValue(":mult", Multiplicity);
query.bindValue(":sol", SOLVANT);
query.bindValue(":geo", Geometry);
query.bindValue(":freq", freq);
query.bindValue(":enth", enthalpy);
query.bindValue(":free_e", free_enthalpy);
query.bindValue(":wei", weight);
if (!query.exec()) {
qWarning() << "The query has failed:" << query.executedQuery();
}

How to access elements returned from QSqlquerymodel set query

I am having trouble understanding how i access the returned elements when i implement a QSqlQueryModel.
I know that you can do
QSqlQuery query;
query.prepare("select * from database");
query.exec();
query.next();
qDebug() << "value in 0 is " << query.value(0).SomeFormat;
So i want to do something like that with QSqlQueryModel (apparently the better way to go).. where i set the query, then i can output the values to another lot of boxes i have.
what i have so far is...
QSqlQuery selectAllUserFields;
selectAllUserFields.prepare(QString("SELECT * from %1 WHERE %2=:firstName and %3=:lastName;")
.arg(dbase::c_userTableName)
.arg(dbase::c_colUserFirstName)
.arg(dbase::c_colUserSecondName));
// finds the index of the current selection, so we can select the row
QModelIndexList tableIndex = m_ui->populatedUserBox->selectionModel()->selection().indexes();
QString firstName = tableIndex.at(0).data().toString();
QString lastName = tableIndex.at(1).data().toString();
QSqlQueryModel dbUsers;
dbUsers.setQuery(selectAllUserFields);
qDebug() << "DEBUG: {temp} " << dbUsers.record(0).value(0).toString();
I am beginnerish, so would appreciate a nudge in the right direction if anyone could assist.
Thanks
Grant
I suggest you have a look at the QSqlQueryModel documentation "Detailed Description" section where it gives an example. To help you further, here is some code that I wrote for an application to iterate over the model result set:
for(int i = 0; i < sqlQueryModel->rowCount(); ++i)
{
qDebug() << sqlQueryModel->record(i).value(0).toString();
}
Another way to do it is to use the function QSqlQueryModel::data(); Again I suggest that you review the documentation here: http://doc-snapshot.qt-project.org/4.8/qsqlquerymodel.html

Boolean variable always returning false

bool Payment::checkUniqueIdentifier(const QString &invoice)
{
qDebug() << "entering Payment: check if the invoice has an associated unique identifier or not for the invoice=" + invoice;
QSqlQuery query(m_storageUserManager->database());
query.prepare("SELECT invoice FROM " + m_invoiceInfoTable + "WHERE invoice=:invoice");
query.bindValue(": invoice", invoice);
query.exec();
query.first();
bool tmp;
tmp = query.isValid();
return tmp;
}
Hi this boolean variable is always returned as false, Can you tell me what could be the possible problem
I was using this function as follows
if(payment->checkUniqueIdentifier("invoice1"))
qDebug() << "It has a unique Identifier";
else
qDebug() << "It dont have a unique Identifier";
Thank you
Regards,
Puneet
There's no space before the where in the query. The table name and where have been concatenated and it reads
SELECT invoice FROM m_invoiceInfoTableWHERE invoice=:invoice

What's the simplest way to execute a query in Visual C++

I'm using Visual C++ 2005 and would like to know the simplest way to connect to a MS SQL Server and execute a query.
I'm looking for something as simple as ADO.NET's SqlCommand class with it's ExecuteNonQuery(), ExecuteScalar() and ExecuteReader().
Sigh offered an answer using CDatabase and ODBC.
Can anybody demonstrate how it would be done using ATL consumer templates for OleDb?
Also what about returning a scalar value from the query?
With MFC use CDatabase and ExecuteSQL if going via a ODBC connection.
CDatabase db(ODBCConnectionString);
db.Open();
db.ExecuteSQL(blah);
db.Close();
You should be able to use OTL for this. It's pretty much:
#define OTL_ODBC_MSSQL_2008 // Compile OTL 4/ODBC, MS SQL 2008
//#define OTL_ODBC // Compile OTL 4/ODBC. Uncomment this when used with MS SQL 7.0/ 2000
#include <otlv4.h> // include the OTL 4.0 header file
#include <stdio>
int main()
{
otl_connect db; // connect object
otl_connect::otl_initialize(); // initialize ODBC environment
try
{
int myint;
db.rlogon("scott/tiger#mssql2008"); // connect to the database
otl_stream select(10, "select someint from test_tab", db);
while (!select.eof())
{
select >> myint;
std::cout<<"myint = " << myint << std::endl;
}
}
catch(otl_exception& p)
{
std::cerr << p.code << std::endl; // print out error code
std::cerr << p.sqlstate << std::endl; // print out error SQLSTATE
std::cerr << p.msg << std::endl; // print out error message
std::cerr << p.stm_text << std::endl; // print out SQL that caused the error
std::cerr << p.var_info << std::endl; // print out the variable that caused the error
}
db.logoff(); // disconnect from the database
return 0;
}
The nice thing about OTL, IMO, is that it's very fast, portable (I've used it on numerous platforms), and connects to a great many different databases.
I used this recently:
#include <ole2.h>
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
#include <oledb.h>
void CMyDlg::OnBnClickedButton1()
{
if ( FAILED(::CoInitialize(NULL)) )
return;
_RecordsetPtr pRs = NULL;
//use your connection string here
_bstr_t strCnn(_T("Provider=SQLNCLI;Server=.\\SQLExpress;AttachDBFilename=C:\\Program Files\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\Data\\db\\db.mdf;Database=mydb;Trusted_Connection=Yes;MARS Connection=true"));
_bstr_t a_Select(_T("select * from Table"));
try {
pRs.CreateInstance(__uuidof(Recordset));
pRs->Open(a_Select.AllocSysString(), strCnn.AllocSysString(), adOpenStatic, adLockReadOnly, adCmdText);
//obtain entire restult as comma separated text:
CString text((LPCWSTR)pRs->GetString(adClipString, -1, _T(","), _T(""), _T("NULL")));
//iterate thru recordset:
long count = pRs->GetRecordCount();
COleVariant var;
CString strColumn1;
CString column1(_T("column1_name"));
for(int i = 1; i <= count; i++)
{
var = pRs->GetFields()->GetItem(column1.AllocSysString())->GetValue();
strColumn1 = (LPCTSTR)_bstr_t(var);
}
}
catch(_com_error& e) {
CString err((LPCTSTR)(e.Description()));
MessageBox(err, _T("error"), MB_OK);
_asm nop; //
}
// Clean up objects before exit.
if (pRs)
if (pRs->State == adStateOpen)
pRs->Close();
::CoUninitialize();
}
Try the Microsoft Enterprise Library. A version should be available here for C++. The SQlHelper class impliments the methods you are looking for from the old ADO days. If you can get your hands on version 2 you can even use the same syntax.