How to output the concrete contents of a QsqlQuery before execution - sql

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();
}

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

QT Sql Error: Not positioned on a valid record

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

Error: cannot dynamically allocate this value type object on native heap

I am trying to create an instance of System::DateTimeon-the-fly and assign it to System::DateTime gDate in case user uses 'P' argument. But, I get the error shown following the code snippet.
case 'P':
gDate=new DateTime(std::stoi(year), std::stoi(month), std::stoi(day));
cout << "Persian Date is: " << pDate.GetDayOfMonth(gDate) << "/" <<
pDate.GetMonth (gDate) << "/" << pDate.GetYear(gDate) << endl;
break;
Error C3255 'System::DateTime': cannot dynamically allocate this value
type object on native heap
What causes the error and how should I prevent it?
Update:
I probably should have said in the first place, I tried also the following definition:
DateTime gDate(std::stoi(year), std::stoi(month), std::stoi(day));
But, I received the error, Error C2360 initialization of 'gDate' is skipped by 'case' label
If you don't need gDate to be a pointer, and you almost certainly do not, try:
case 'P':
{
DateTime gDate(std::stoi(year), std::stoi(month), std::stoi(day));
cout << "Persian Date is: " << pDate.GetDayOfMonth(gDate) << "/" <<
pDate.GetMonth (gDate) << "/" << pDate.GetYear(gDate) << endl;
}
break;
The braces establish a scope for gDate, ensuring deletion when the program exits the braces.
CLI/CLR C++ is a different beast from C++ and has some different semantics.
CLI/C++ has added a concepts of value and ref structs and classes. These are objects with automatic lifetime control. The .Net runtime, not the programmer, decides when they live and die, and this requires different syntax.
Those tagged value are intended to be used as one would use a Plain Old Datatype like an int or a double. Create 'em as a temporary, use them, and let the stack or whatever other method of managing temporary variables is in use take care of the clean-up. You can point to them, but it is not recommended.
ref structs and classes are designed with referenced use in mind and are open game for pointers, so long as they are garbage collected pointers.
System::DateTime is a value struct, so what follows strays from its recommended use. As a pointer, System::DateTime must either be used as a garbage collected pointer with ^ in place of * and allocated with gcnew in place of new or as a variable with a defined scope.
If gDate must be a pointer, it must be defined
DateTime ^ gDate;
And allocating it requires
gDate = gcnew DateTime(std::stoi(year), std::stoi(month), std::stoi(day));
When there are no further references to this allocated object, gDate and any copies of gDate have gone out of scope, the .Net runtime's garbage collector will destroy it.
As explained here, you can create DateTime on the stack, but not on the heap.
Try like this:
DateTime gDate(std::stoi(year), std::stoi(month), std::stoi(day));
cout << "Persian Date is: " << pDate.GetDayOfMonth(gDate) << "/" <<
pDate.GetMonth (gDate) << "/" << pDate.GetYear(gDate) << endl;
break;
alternatively, you can use gcnew to allocate managed memory:
DateTime^ gDate = gcnew DateTime(std::stoi(year), std::stoi(month), std::stoi(day));

YAML ofstream emitter

I find this example:
ofstream ofstr("output.yaml");
YAML::Emitter out(ofstr);
out << some_large_document;
// not necessary anymore:
// ofstr << out.c_str()
But when i try use it, i have:
D:\work\C\map.cpp||In function `int main()':|
D:\work\C\map.cpp|24|error: no matching function for call to `YAML::Emitter::Emitter(std::ofstream&)'|
D:\work\C\yaml-cpp\emitter.h|23|note: candidates are: YAML::Emitter::Emitter(YAML::Emitter&)|
D:\work\C\yaml-cpp\emitter.h|25|note: YAML::Emitter::Emitter()|
||=== Build finished: 1 errors, 0 warnings ===|
There's no constructor to YAML::Emitter that takes a stream. (Where did you find that example?)
Instead, you do need to use the commented out line:
ofstream ofstr("output.yaml");
YAML::Emitter out;
out << some_large_document;
ofstr << out.c_str(); // is necessary!

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.