PDA

View Full Version : QODBC Driver - unable to bind variable



AlphaWolfXV
14th September 2011, 13:55
OS: Win 7 32bit
QT Creator 2.2.1 QT 4.7.4

I am just starting working with the ODBC driver and MSSQL. I have a basic program where I want to modify data, however I am running into the following error:
"QODBCResult::exec: unable to bind variable: "[Microsoft][ODBC SQL Server Driver]Optional feature not implemented".
This error is generated on my mapper->submit() (set in manual submit mode), when I navigate from first to next to last to previous and when I try to change data. On a data change it basically just discards the changes made and does not submit them to the model. Code is below, but the question is do I need to implement some of the "optional features" of ODBC or is there another method for using ODBC to navigate record sets?
Thanks, in advance, for your help!
AlphaWolfXV
employeeform.h

#ifndef EMPLOYEEFORM_H
#define EMPLOYEEFORM_H

#include <QtGui>
#include <QDialog>
#include <QtSql>
#include "../qtWidgets/recordnav/dbrecordnav.h"
//tEmployees
enum{
tEmployee_Id = 0,
tEmployee_NameCode = 1,
tEmployee_FName = 2,
tEmployee_LName = 3,
tEmployee_DepartmentId = 4,
tEmployee_StatusId = 5,
tEmployee_StartDate = 6};
//tDepartment Enum
enum{
tDepartment_Id = 0,
tDepartment_Code = 1,
tDepartment_Name = 2,
tDepartment_Supervisor = 3,
tDepartment_StatusId = 4 };
//tStatus Enum
enum{
tStatus_Id = 0,
tStatus_Desc = 1 };


class employeeForm : public QDialog
{
Q_OBJECT
public:
employeeForm(int id,QWidget *parent = 0);
private slots:
void addEmployee();
void deleteEmployee();
void go2Prev();
void go2First();
void go2Last();
void go2Next();
void go2Rec(int a);
private:
QSqlRelationalTableModel *tableModel;
QDataWidgetMapper *mapper;
QLabel *lblNameCode, *lblFName,*lblLName,*lblDept,*lblStatus, *lblStartDate;
QLineEdit *leNameCode, *leFName, *leLName;
QDateEdit *deStartDate;
QComboBox *cbDept, *cbStatus;
QPushButton *bFirst, *bPrev, *bNext, *bLast, *bAdd, *bDelete, *bClose;
dbrecordnav *nav;
};

#endif // EMPLOYEEFORM_H


Thanks again, and looking forward to replies!
AlphaWolfXV

employeeform.cpp

#include "employeeform.h"

employeeForm::employeeForm(int id, QWidget *parent)
:QDialog(parent)
{
leNameCode = new QLineEdit;
lblNameCode = new QLabel(tr("Alias"));
lblNameCode->setBuddy(leNameCode);
QHBoxLayout *hblNameCode = new QHBoxLayout();
hblNameCode->addWidget(lblNameCode);
hblNameCode->addWidget(leNameCode);

cbDept = new QComboBox;
lblDept = new QLabel(tr("Department"));
lblDept->setBuddy(cbDept);
QHBoxLayout *hblDept = new QHBoxLayout();
hblDept->addWidget(lblDept);
hblDept->addWidget(cbDept);

leFName = new QLineEdit;
lblFName = new QLabel(tr("First Name:"));
lblFName->setBuddy(leFName);
QHBoxLayout *hblName = new QHBoxLayout();
hblName->addWidget(lblFName);
hblName->addWidget(leFName);
hblName->addSpacing(20);

leLName = new QLineEdit;
lblLName = new QLabel(tr("Last Name:"));
lblLName->setBuddy(leLName);
hblName->addWidget(lblLName);
hblName->addWidget(leLName);

cbStatus = new QComboBox;
lblStatus = new QLabel(tr("Employment Status:"));
lblStatus->setBuddy(cbStatus);
QHBoxLayout *hblStatus = new QHBoxLayout();
hblStatus->addWidget(lblStatus);
hblStatus->addWidget(cbStatus);

deStartDate = new QDateEdit;
deStartDate->setCalendarPopup(true);
QDate today = QDate::currentDate();
deStartDate->setDateRange(today.addDays(-90),today.addDays(90));
deStartDate->setDate(today);
lblStartDate = new QLabel(tr("Start Date:"));
lblStartDate->setBuddy(deStartDate);
QHBoxLayout *hblStartDate = new QHBoxLayout();
hblStartDate->addWidget(lblStartDate);
hblStartDate->addWidget(deStartDate);

bClose = new QPushButton("&Close");

//finally lets set up the model
tableModel = new QSqlRelationalTableModel(this);
tableModel->setTable("tEmp");
tableModel->setRelation(tEmployee_DepartmentId, QSqlRelation("tDepartment","idtDepartment","tDepartment_Name"));
tableModel->setRelation(tEmployee_StatusId,QSqlRelation("tStatus","idtStatus","tStatus_Code"));
tableModel->setEditStrategy(QSqlTableModel::OnRowChange);
//tableModel->setSort(tEmployee_NameCode,Qt::AscendingOrder);
tableModel->select();

//uses the relation set earlier when setRelation() was called.
//because of this, we cannot just use the table enums to get the model row, they may be different

QSqlTableModel *relationModel = tableModel->relationModel(tEmployee_DepartmentId);
cbDept->setModel(relationModel);
cbDept->setModelColumn(relationModel->fieldIndex("tDepartment_Name"));//cbDept->setModelColumn(tDepartment_Name);
QSqlTableModel *relationModel_status = tableModel->relationModel(tEmployee_StatusId);
cbStatus->setModel(relationModel_status);
cbStatus->setModelColumn(relationModel_status->fieldIndex("tStatus_Code"));//cbStatus->setModelColumn(tStatus_Desc);

//now we can map the records from the database into the form...
mapper = new QDataWidgetMapper(this);
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setModel(tableModel);
mapper->setItemDelegate(new QSqlRelationalDelegate(this));
mapper->addMapping(leNameCode, tEmployee_NameCode);
mapper->addMapping(leFName,tEmployee_FName);
mapper->addMapping(leLName,tEmployee_LName);
mapper->addMapping(cbDept, tEmployee_DepartmentId);
mapper->addMapping(deStartDate,tEmployee_StartDate);
mapper->addMapping(cbStatus,tEmployee_StatusId);

//finally now if the form was called with a valid id, then populated with that Ids records...
//otherwise just use the first record ...
if(id != -1)
{
for(int row = 0; row < tableModel->rowCount(); ++row)
{
QSqlRecord record = tableModel->record(row);
if(record.value(tEmployee_Id).toInt() == id)
{
mapper->setCurrentIndex(row);
break;
}
}
}
else
mapper->toFirst();

nav = new dbrecordnav(this);
nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());

QVBoxLayout *vblMain = new QVBoxLayout();
vblMain->addLayout(hblNameCode);
vblMain->addLayout(hblDept);
vblMain->addLayout(hblName);
vblMain->addLayout(hblStartDate);
vblMain->addLayout(hblStatus);
vblMain->addWidget(nav);
setLayout(vblMain);

//finally connect statements
connect(nav,SIGNAL(first()),this,SLOT(go2First())) ;
connect(nav,SIGNAL(prev()),this,SLOT(go2Prev()));
connect(nav,SIGNAL(next()),this,SLOT(go2Next()));
connect(nav,SIGNAL(last()),this,SLOT(go2Last()));
connect(nav,SIGNAL(newrec()),this,SLOT(addEmployee ()));
connect(nav,SIGNAL(deleterec()),this,SLOT(deleteEm ployee()));
connect(nav,SIGNAL(changeRecord(int)),this,SLOT(go 2Rec(int)));
connect(bClose,SIGNAL(clicked()),this,SLOT(close() ));
}
void employeeForm::go2First()
{
int row = mapper->currentIndex();
if(! mapper->submit())
{
qDebug()<<"go2first//lasterror:"<<tableModel->lastError().text();
tableModel->revertAll();
}
mapper->toFirst();
nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());
}
void employeeForm::go2Prev()
{
int row = mapper->currentIndex();
if(! mapper->submit())
{
qDebug()<<"go2prev//lasterror:"<<tableModel->lastError().text();
tableModel->revertRow(row);
}
if(row > 0)
row--;
mapper->setCurrentIndex(row);

nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());
}
void employeeForm::go2Next()
{
int row = mapper->currentIndex();
if(!mapper->submit())
{
qDebug()<<"go2next//lasterror:"<<tableModel->lastError().text();
tableModel->revertRow(row);
}

mapper->setCurrentIndex(row);
mapper->toNext();
nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());
}
void employeeForm::go2Last()
{
int row = mapper->currentIndex();
if(!mapper->submit())
{
qDebug()<<"go2last//lasterror:"<<tableModel->lastError().text();
tableModel->revertRow(row);
row--;
}
mapper->setCurrentIndex(row);
mapper->toLast();
nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());
}

void employeeForm::go2Rec(int a)
{
if((a-1) <= tableModel->rowCount())
mapper->setCurrentIndex(a-1);
else
{
mapper->toLast();
nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());
}
}
void employeeForm::addEmployee()
{
//add records at the end of the list
//mapper->submit();
mapper->toLast();
int row = mapper->currentIndex();
qDebug()<<"Row Num" << row;
tableModel->insertRow(row+1);
qDebug()<<"After Insert Row";
mapper->setCurrentIndex(row+1);
qDebug()<<"After set Curret Index.";
//set the nav counts up 1
nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());
leNameCode->clear();
leFName->clear();
leLName->clear();
cbDept->clear();
cbStatus->clear();
deStartDate->setDate(QDate::currentDate());
leNameCode->setFocus();
}
void employeeForm::deleteEmployee()
{
int row = mapper->currentIndex();
tableModel->removeRow(row);
mapper->submit();
mapper->setCurrentIndex(qMin(row,tableModel->rowCount()-1));
nav->setCurrentRec(mapper->currentIndex()+1);
nav->setTotalRec(tableModel->rowCount());
}