QODBC problem with VisualStudio 2017 & SQL Server 2017



  • Hello!

    I am trying to create a LoginForm but it keeps hitting a breakpoint at QSqlDatabase db = QSqlDatabase::addDatabase("QODBC"); saying "unhandled exception ntdll.dll a heap has been corrupted".

    Here is my code(I am using Visual Studio 2017 with QtVS and SQL Server Express 2017 for the database) :

    #include "f1_system.h"
    #include <QtSql/qsqldatabase.h>
    #include <QtSql/qsqlquery.h>
    #include <QtSql/qsqlerror.h>
    #include <QtSql/qsqldriver.h>
    
    
    F1_System::F1_System(QWidget *parent)
    	: QMainWindow(parent)
    {
    	ui.setupUi(this);
    
    	connect(ui.loginPushButton, SIGNAL(clicked()), this, SLOT(validateLogin()));
    }
    
    void F1_System::validateLogin() {
    	QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
    	db.setConnectOptions();
    	QSqlQuery qry;
    	QString connectionString = "Driver={SQL Server};Server=DESKTOP-4K9MAS2\\SQLEXPRESS01;Database=Formula1_BD;Trusted_Connection=yes;";
    	
    	db.setDatabaseName(connectionString);
    	db.open();
    
    	if (db.isOpen()){
    		qry.prepare("SELECT Username FROM Users WHERE Username = '" + ui.usernameInputField->text() + "' AND Userpassword = '" + ui.passwordInputField->text() + "';");
    
    		if (qry.exec()) {
    			if (qry.next())
    				ui.label->setText("Status: You are logged in!");
    			else
    				ui.label->setText("Status: Wrong credentials!\nTry again!");
    
    		}
    		else
    			ui.label->setText(qry.lastError().text());
    	}
    	else
    		ui.label->setText("Failed to connect to the databasef!");
    
    	db.close();
    }
    

    Does anybody know a solution?

    If i just skip over those breakpoints from debugger, it validates my login. So it does what it should do.


  • Qt Champions 2018

    @Ovidiu_GCO Why do you call addDatabase inside validateLogin? You should call it once, for example in the constructor.
    "but it keeps hitting a breakpoint" - I don't get it - did you set a breakpoint at that line? A break point is there to stop when running your app through the debugger.



  • @jsulm Thank you for your reply.
    I moved "addDatabase" in the constructor, as you suggested (also declared "db" as a field of F1_System class) and now the "unhandled exception" is hitting at db.close().

    I didn't place any breakpoints, but it says this :

    F1_System.exe has triggered a breakpoint. occurred
    

    If i press "Continue" in the debugger, it says:

    Unhandled exception at 0x00007FFEE6DA4D3B (ntdll.dll) in F1_System.exe: 0xC0000374: A heap has been corrupted (parameters: 0x00007FFEE6E097B0). occurred
    

    0_1542196915809_Unhandled exception.PNG

    Any idea on what could i do now?
    Thank you for your time.


  • Qt Champions 2018

    @Ovidiu_GCO Why do you constantly open and close the db connection?
    Also, there is no need for this db member. You can get the connection at any time using

    QSqlDatabase db = QSqlDatabase::database();
    

    as explained in http://doc.qt.io/qt-5/qsqldatabase.html
    And what is this:

    qry.~QSqlQuery();
    

    !!!
    Why do you call destructor explicitly?!



  • @jsulm That is a mistake. I became desperate and I started using anything that came in my mind.

    I do not understand what do you mean by "Also, there is no need for this db member. You can get the connection at any time using"

    QSqlDatabase db = QSqlDatabase::database();
    

    How should i do it?


  • Qt Champions 2018

    @Ovidiu_GCO "also declared "db" as a field of F1_System class" - this is not needed, as you can get your db at any time as I shown you:

    QSqlDatabase db = QSqlDatabase::database("QODBC");
    

    So, there is no need to declare db as a field/member of F1_System class.
    Did you read the documentation? http://doc.qt.io/qt-5/qsqldatabase.html



  • @jsulm I tried to read it, but I am beginner and it is not very clear for me. Honestly, i do not really understand most of it.

    I've tried this:

    #include "f1_system.h"
    #include <QtSql/qsqldatabase.h>
    #include <QtSql/qsqlquery.h>
    #include <QtSql/qsqlerror.h>
    #include <QtSql/qsqldriver.h>
    
    
    F1_System::F1_System(QWidget *parent)
    	: QMainWindow(parent)
    {
    	ui.setupUi(this);
    	QString connectionString = "Driver={SQL Server};Server=DESKTOP-4K9MAS2\\SQLEXPRESS01;Database=Formula1_BD;Trusted_Connection=yes;";
    	QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
    	
    	db.setDatabaseName(connectionString);
    
    	connect(ui.loginPushButton, SIGNAL(clicked()), this, SLOT(validateLogin()));
    }
    
    void F1_System::validateLogin() {
    	QSqlQuery qry;
    	QSqlDatabase db = QSqlDatabase::database("QODBC");
    
    	db.open();
    
    	if (db.isOpen()){
    		qry.prepare("SELECT Username FROM Users WHERE Username = '" + ui.usernameInputField->text() + "' AND Userpassword = '" + ui.passwordInputField->text() + "';");
    
    		if (qry.exec()) {
    			if (qry.next())
    				ui.label->setText("Status: You are logged in!");
    			else
    				ui.label->setText("Status: Wrong credentials!\nTry again!");
    
    		}
    		else
    			ui.label->setText(qry.lastError().text());
    	}
    	else
    		ui.label->setText("Failed to connect to the database!");
    }
    

    But it still didn't change a thing...


  • Qt Champions 2018

    @Ovidiu_GCO Where does it crash now?
    Also, now you open the db each time F1_System::validateLogin() is called. Why don't you do it in constructor of F1_System and close it in the corresponding destructor?



  • @jsulm In the last form posted, it is occurring at the last curly-bracket(the one that closes "validateLogin()").

    I tried to do as you said, db.open() in the constructor and db.close() in the destructor, but without making QSqlDatabase db a member of the F1_System class it says that identifier "db" is undefined, both at db.close(), in the destructor, and at db.isOpen(), in the validateLogin() method.

    Code:

    #include "f1_system.h"
    #include <QtSql/qsqldatabase.h>
    #include <QtSql/qsqlquery.h>
    #include <QtSql/qsqlerror.h>
    #include <QtSql/qsqldriver.h>
    
    
    F1_System::F1_System(QWidget *parent)
    	: QMainWindow(parent)
    {
    	ui.setupUi(this);
    	QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
    	QString connectionString = "Driver={SQL Server};Server=DESKTOP-4K9MAS2\\SQLEXPRESS01;Database=Formula1_BD;Trusted_Connection=yes;";
    
    	db.setDatabaseName(connectionString);
    	db.open();
    
    	connect(ui.loginPushButton, SIGNAL(clicked()), this, SLOT(validateLogin()));
    }
    
    F1_System::~F1_System() {
    	db.close();
    }
    void F1_System::validateLogin() {
    	QSqlQuery qry;
    
    	db = QSqlDatabase::database("QODBC");
    
    	if (db.isOpen()){
    		qry.prepare("SELECT Username FROM Users WHERE Username = '" + ui.usernameInputField->text() + "' AND Userpassword = '" + ui.passwordInputField->text() + "';");
    
    		if (qry.exec()) {
    			if (qry.next())
    				ui.label->setText("Status: You are logged in!");
    			else
    				ui.label->setText("Status: Wrong credentials!\nTry again!");
    
    		}
    		else
    			ui.label->setText(qry.lastError().text());
    	}
    	else
    		ui.label->setText("Failed to connect to the databasef!");
    }
    

    After that, I tried to make QSqlDatabase db a member of the class, but the login still fails...



  • @jsulm You were right. I finally understood what you meant by getting the db at any time. Thank you very much for your help!

    This is my working code:

    #include "f1_system.h"
    #include <QtSql/qsqldatabase.h>
    #include <QtSql/qsqlquery.h>
    #include <QtSql/qsqlerror.h>
    #include <QtSql/qsqldriver.h>
    
    
    F1_System::F1_System(QWidget *parent)
    	: QMainWindow(parent)
    {
    	ui.setupUi(this);
    	
    	QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", "dataB");
    	QString connectionString = "Driver={SQL Server};Server=DESKTOP-4K9MAS2\\SQLEXPRESS01;Database=Formula1_BD;Trusted_Connection=yes;";
    	db.setDatabaseName(connectionString);
    
    	connect(ui.loginPushButton, SIGNAL(clicked()), this, SLOT(validateLogin()));
    }
    F1_System::~F1_System() {
    
    	QSqlDatabase::database("dataB").close();
    }
    void F1_System::validateLogin() { 
    	
    	if (QSqlDatabase::database("dataB").open()) {
    		QString selectUser("SELECT Username FROM Users WHERE Username = '" + ui.usernameInputField->text() + "' AND Userpassword = '" + ui.passwordInputField->text() + "';");
    		 QSqlQuery qry(selectUser, QSqlDatabase::database("dataB"));
    		
    		if (qry.next())
    			ui.label->setText("Status: You are logged in!");
    		else
    			ui.label->setText("Status: Wrong credentials!\nTry again!");
    	}
    	else
    		ui.label->setText("Failed to connect to the database!");
    
    }