前几天发了一个不完整版的ODBC接口类,昨天重新整理、测试了一下,重新发一个。
odbc_dbmgr.h:
#ifndef __ODBC_DBMGR_H__
#define __ODBC_DBMGR_H__
#include <Windows.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
class ODBC_DBMGR{
public:
ODBC_DBMGR();
virtual ~ODBC_DBMGR();
static ODBC_DBMGR* GetInstance();
public: // 用法:使用Open打开一个DSN,使用ExecSql执行SQL语句,使用Close关闭打开的DSN
int ODBC_Open(const char* szDSN, const char* szUser, const char* szPassword);
void ODBC_Close(void);
int ODBC_ExecSql(char* szSql);
// 执行查询之后下面函数起作用
short ODBC_GetResultCols(void); // 返回记录集的列
int ODBC_GetResultRows(void); // 返回记录集条数
int ODBC_BindCol2Char(short nCol, char* szColValue, int nColValueLen); // 绑定列为C_char类型
int ODBC_BindCol2Long(short nCol, long &nColValue); // 绑定列为long型
SQLRETURN ODBC_Fetch();
// int ODBC_BindCol2Bit(short nCol);
private:
SQLSMALLINT ODBC_Init(void);
private:
SQLHENV m_henv; // ODBC 环境
SQLHDBC m_hdbc; // ODBC 句柄
SQLHSTMT m_hstmt; // 返回值句柄
bool m_bIsConnected; // 是否连接的标志
static ODBC_DBMGR* m_pDB;
};
odbc_dbmgr.cpp:
#include <stdio.h>
#include "odbc_dbmgr.h"
// 遇到错误返回的宏
#define FAILPAUSE(ret) /
if (SQL_SUCCESS != ret) { /
printf("SQL Errors:%d/n", ret); /
ODBC_Close(); /
return ret; }
ODBC_DBMGR*ODBC_DBMGR::m_pDB = NULL;
ODBC_DBMGR::ODBC_DBMGR()
{
m_hdbc = NULL;
m_henv = NULL;
m_hstmt = NULL;
m_bIsConnected = false;
}
ODBC_DBMGR::~ODBC_DBMGR()
{
ODBC_Close();
}
ODBC_DBMGR* ODBC_DBMGR::GetInstance()
{
if (m_pDB == NULL)
{
m_pDB = new ODBC_DBMGR;
}
return m_pDB;
}
// 初始化,完成各种环境设置
SQLSMALLINT ODBC_DBMGR::ODBC_Init()
{
SQLRETURN ret;
ret = ::SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_henv);
FAILPAUSE(ret);
ret = ::SQLSetEnvAttr(m_henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
FAILPAUSE(ret);
ret = ::SQLAllocHandle(SQL_HANDLE_DBC, m_henv, &m_hdbc);
FAILPAUSE(ret);
return SQL_SUCCESS;
}
//
// 打开一个DSN,打开之前首先初始化
int ODBC_DBMGR::ODBC_Open(const char* szDSN, const char* szUser, const char* szPassword)
{
SQLRETURN ret;
ret = ODBC_Init();
FAILPAUSE(ret);
ret = ::SQLConnect(m_hdbc,
(SQLCHAR*)szDSN, SQL_NTS,
(SQLCHAR*)szUser, SQL_NTS,
(SQLCHAR*)szPassword, SQL_NTS);
if (SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret)
{
m_bIsConnected = true;
ret = ::SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt);
FAILPAUSE(ret);
}
return 0;
}
//
// 执行SQL语句
int ODBC_DBMGR::ODBC_ExecSql(char* szSql)
{
SQLRETURN ret;
ret = ::SQLPrepare(m_hstmt, (SQLCHAR*)szSql, SQL_NTS);
FAILPAUSE(ret);
ret = ::SQLExecute(m_hstmt);
FAILPAUSE(ret);
return 0;
}
//
//返回结果集列数
short ODBC_DBMGR::ODBC_GetResultCols()
{
short nCols = 0;
::SQLNumResultCols(m_hstmt, &nCols);
return nCols;
}
//
// 绑定某列为字符串
int ODBC_DBMGR::ODBC_BindCol2Char(short nCol, char* szColValue, int nColValueLen)
{
SQLLEN cb;
SQLRETURN ret;
ret = ::SQLBindCol(m_hstmt, nCol, SQL_C_CHAR, szColValue, nColValueLen, &cb);
FAILPAUSE(ret);
//ret = ::SQLFetch(m_hstmt);
//FAILPAUSE(ret);
return 0;
}
//
// 绑定某列为int
int ODBC_DBMGR::ODBC_BindCol2Long(short nCol, long& nColValue)
{
SQLLEN cb;
SQLRETURN ret;
ret = ::SQLBindCol(m_hstmt, nCol, SQL_C_LONG, &nColValue, sizeof(long), &cb);
FAILPAUSE(ret);
//ret = ::SQLFetch(m_hstmt);
//FAILPAUSE(ret);
return 0;
}
int ODBC_DBMGR::ODBC_GetResultRows()
{
SQLRETURN ret;
SQLLEN value;
ret = ::SQLRowCount(m_hstmt, &value);
if (SQL_SUCCESS == ret)
return value;
else
return -1;
}
SQLRETURN ODBC_DBMGR::ODBC_Fetch()
{
return ::SQLFetch(m_hstmt);
}
// 关闭连接
void ODBC_DBMGR::ODBC_Close()
{
if (m_henv){
if (m_hdbc){
if (m_bIsConnected){
if (m_hstmt){
::SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
}
::SQLDisconnect(m_hdbc);
m_bIsConnected = false;
}
::SQLFreeHandle(SQL_HANDLE_DBC, m_hdbc);
m_hdbc = NULL;
}
::SQLFreeHandle(SQL_HANDLE_ENV, m_henv);
m_henv = NULL;
}
}
测试用的main:
#include <stdio.h>
#include "odbc_dbmgr.h"
// main
struct tagGameID1{
char szGameID[15];
long nLevel;
long nFace;
long nStrength;
long nSpirit;
long nDex;
long nPower;
int nFame;
int nHP;
int nMP;
int nSTotalBonus;
};
int main(int argc, char* argv[])
{
ODBC_DBMGR db;
int col = 0;
int row = 0;
struct tagGameID1 stru_gameid;
db.ODBC_Open("RMEBrain0", "sa", "");
db.ODBC_ExecSql((char*)"SELECT * FROM tblGameID1");
col = db.ODBC_GetResultCols();
db.ODBC_BindCol2Char(2, stru_gameid.szGameID, 14);
db.ODBC_BindCol2Long(4, stru_gameid.nLevel);
db.ODBC_BindCol2Long(14, stru_gameid.nStrength);
db.ODBC_BindCol2Long(15, stru_gameid.nSpirit);
db.ODBC_BindCol2Long(16, stru_gameid.nDex);
db.ODBC_BindCol2Long(17, stru_gameid.nPower);
while (0 == db.ODBC_Fetch())
{
printf("%s-%d-%d-%d-%d-%d/n", stru_gameid.szGameID, stru_gameid.nLevel,
stru_gameid.nStrength,stru_gameid.nSpirit,
stru_gameid.nDex,stru_gameid.nPower);
}
getchar();
db.ODBC_Close();
}
里面提供了ODBC_DBMGR的一个singleton入口。经过测试,该简单接口完整可用。但现在缺少批查、批改、事务等。