1. 程式人生 > >QT操作Oracle資料庫(事務、儲存過程)

QT操作Oracle資料庫(事務、儲存過程)

QT操作Oracle資料庫可以使用QODBC、QOCI兩種驅動,這裡使用QODBC驅動。在使用QOCI驅動操作oracle時,事務不能回滾,可能是我編譯的QOCI驅動有問題,但是暫時沒有找到原因。

#ifndef QTTEST_H
#define QTTEST_H

#include <QtGui/QMainWindow>
#include "ui_qttest.h"
#include <QSqlDatabase>

class QSqlQuery;
class QSqlError;
class QVariant;

class qttest : public QMainWindow
{
	Q_OBJECT

public:
	qttest(QWidget *parent = 0, Qt::WFlags flags = 0);
	~qttest();

private:
	Ui::qttestClass ui;
	QSqlDatabase db;

public:
	void createDatabase();
	bool connectDatabase();
	void closeDatabase();

	void insertMoreData();
	void queryData();

private slots:
	//刪除操作採用事務處理
	void on_btnDel_clicked();
	void on_btnCal_clicked();
	void on_btnDelOk_clicked();

	//呼叫儲存過程
	void on_btnProcedure_clicked();
};
#include "qttest.h"
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlDriver>
#include <QVariant>
#include <QSqlError>
#include <QDebug>

qttest::qttest(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);

	//列印QT支援的資料庫驅動型別
	qDebug() << QSqlDatabase::drivers();

	createDatabase();

	connectDatabase();

	insertMoreData();

	queryData();
}

qttest::~qttest()
{

}

void qttest::createDatabase()
{
	//新增oracle資料庫驅動
	db = QSqlDatabase::addDatabase("QODBC");

	//伺服器ip和埠號
	db.setPort(1521);
	db.setHostName("localhost");

	//***資料來源配置時填寫的那個DataSourceName
	db.setDatabaseName("Oracle");

	//使用者名稱和密碼
	db.setUserName("scott");
	db.setPassword("tiger");
}

bool qttest::connectDatabase()
{
	if(db.isOpen())
		return true;

	if (!db.open())
	{
		qDebug() << "Error: Failed to connect database." << db.lastError();
		return false;
	}
	return true;
}

//批量插入資料
void qttest::insertMoreData()
{
	connectDatabase();

	QSqlQuery sql_query(db);

	QString insert_query = "insert into dept values(? ,? ,?)";
	sql_query.prepare(insert_query);

	//給欄位設定內容
	QVariantList deptnolist;
	deptnolist << 60 << 70;

	QVariantList dnamelist;
	dnamelist << "SALES" << "SALES";

	QVariantList loclist;
	loclist << "ShangHai" << "GuangZhou";

	//按順序給欄位繫結相應的值
	sql_query.addBindValue(deptnolist);
	sql_query.addBindValue(dnamelist);
	sql_query.addBindValue(loclist);

	//執行預處理命令
	sql_query.execBatch();
}

//查詢資料庫
void qttest::queryData()
{
	connectDatabase();

	QSqlQuery sql_query(db);

	QString select_sql = "select* from dept where dname = \'SALES\'";

	if (!sql_query.exec(select_sql))
	{
		qDebug() <<sql_query.lastError();
	} 
	else
	{
		int lieshu = sql_query.record().count();
		int hangshu = sql_query.size();

		qDebug() << "列數:" << lieshu <<endl
			     << "行數:" << hangshu <<endl;

		qDebug() <<sql_query.lastError();

		while (sql_query.next())
		{
			qDebug() << sql_query.value(0).toInt()
				     << sql_query.value(1).toString()
					 << sql_query.value(2).toString();
		}
	}
}

//事務進行刪除操作
void qttest::on_btnDel_clicked()
{
	connectDatabase();

	QSqlQuery sql_query(db);

	bool bbb = QSqlDatabase::database().driver()->hasFeature(QSqlDriver::Transactions);

	//開啟一個事務
	bool b = db.transaction();

	QString delete_sql = "delete from dept where deptno = ?";
	sql_query.prepare(delete_sql);
	sql_query.addBindValue(50);

	sql_query.exec();
	qDebug() <<sql_query.lastError();
}

//取消按鈕
void qttest::on_btnCal_clicked()
{
	bool bRet = QSqlDatabase::database().rollback();
}

//確定刪除
void qttest::on_btnDelOk_clicked()
{
	bool bRet = QSqlDatabase::database().commit();
}

/**QT呼叫儲存過程**/
	/* 儲存過程
	create or replace procedure zzc_dept1 (
		num_deptno  in number,
		var_ename in varchar2,
		var_loc in varchar2)is
		begin
		insert into dept
		values(num_deptno,var_ename,var_loc);
	commit;
	end zzc_dept1;
	*/
void qttest::on_btnProcedure_clicked()
{
	QString pro_sql = "call zzc_dept1(? ,? ,?)";

	QSqlQuery sql_query(db);
	sql_query.prepare(pro_sql);

	sql_query.bindValue(0,61);
	sql_query.bindValue(1,"XIAOSHOU");
	sql_query.bindValue(2,"BaoDing");

	sql_query.exec();
}

void qttest::closeDatabase()
{
	if (db.isOpen())
	{
		db.close();
	}
}

關於QODBC驅動的配置使用方法,前面一篇文章中有介紹。