📄 myodbc.cpp
字号:
// Odbc1.cpp: implementation of the CMyODBC class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyODBC.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#pragma comment(lib, "ODBC32")
extern CString gStr_dsname,gStr_username,gStr_passwd;
CMyODBC::CMyODBC()
{
this->m_hdbc = NULL;
this->m_henv = NULL;
this->m_hstmt = NULL;
this->m_retcode = 0;
m_pSet = NULL;
}
CMyODBC::~CMyODBC()
{
DisConnect();
}
BOOL CMyODBC::ConnectDB(const char *cpServerName,const char *cpUserName,const char *cpPassword)
{
//分配环境句柄
m_retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_henv);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
DEBUGINFO("分配环境句柄失败!");
return FALSE;
}
/* Set the ODBC version environment attribute */
m_retcode = SQLSetEnvAttr(m_henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
//ReportError(m_henv, SQL_HANDLE_ENV, "设置odbc版本号时失败!");
DEBUGINFO("设置odbc版本号时失败!");
return FALSE;
}
/*分配连接句柄 */
m_retcode = SQLAllocHandle(SQL_HANDLE_DBC, m_henv, &m_hdbc);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
//ReportError(m_henv, SQL_HANDLE_ENV,"分配连接句柄失败!");
DEBUGINFO("分配连接句柄失败!");
return FALSE;
}
/* 连接数据库 */
m_retcode = SQLConnect(m_hdbc, (SQLCHAR*) cpServerName, SQL_NTS, (SQLCHAR*) cpUserName, SQL_NTS, (SQLCHAR*) cpPassword, SQL_NTS);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
//ReportError(m_hdbc, SQL_HANDLE_DBC,"连接数据库失败!");
DEBUGINFO("连接数据库失败!");
return FALSE;
}
return TRUE;
}
BOOL CMyODBC::DisConnect()
{
if(m_hstmt != NULL)
{
SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
m_hstmt = NULL;
}
if(this->m_hdbc != NULL)
{
SQLDisconnect(m_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, m_hdbc);
m_hdbc = NULL;
}
if(this->m_henv != NULL)
{
SQLFreeHandle(SQL_HANDLE_ENV, m_henv);
m_henv = NULL;
}
if(this->m_pSet != NULL)
{
m_pSet = NULL;
}
return TRUE;
}
BOOL CMyODBC::PrepareSqlEx(const char *cpSql, CODBCSet &rset)
{
CString strWarn, strError;;
if(this->m_hstmt != NULL)
{
SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
m_hstmt = NULL;
}
if(this->m_hdbc == NULL)
{
DEBUGINFO("没有连接数据库,请先进行联接!");
return FALSE;
}
m_retcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hdbc, SQL_HANDLE_DBC,"分配语句句柄失败,不能执行");
return FALSE;
}
this->m_pSet = &rset;
if(!m_pSet->IsEmpty())
{
m_pSet->Empty();
}
m_retcode = SQLExecDirect(m_hstmt, (unsigned char *)cpSql, SQL_NTS);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT, "执行sql语句失败");
SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
m_hstmt = NULL;
return FALSE;
}
SQLSMALLINT iNumCols = 0;
m_retcode = SQLNumResultCols(m_hstmt, &iNumCols);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT, "取列数失败,不能执行");
return FALSE;
}
m_pSet->m_cols = iNumCols;
m_pSet->m_coldata = new COL_DATA_ODBC[iNumCols];
if (m_pSet->m_coldata == NULL)
{
DEBUGINFO("分配每个列内存空间失败\n");
return FALSE;
}
m_pSet->m_coldatafmt = new COL_DATAFMT_ODBC[iNumCols];
if(m_pSet->m_coldatafmt == NULL)
{
DEBUGINFO("分配每个列信息的内存空间失败\n");
delete []m_pSet->m_coldata;
m_pSet->m_coldata = 0;
return FALSE;
}
SQLINTEGER dataLen;
SQLSMALLINT SqlType, cType;
char SqlColName[100];
SQLSMALLINT StringLeng;
SqlType = SQL_INTEGER ;
for(int iCount = 0; iCount <iNumCols; iCount++)
{
m_retcode = SQLColAttribute(m_hstmt, ((SQLUSMALLINT)iCount) + 1, SQL_DESC_NAME, (SQLPOINTER)SqlColName, 100, &StringLeng, 0);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT,"取列名时失败");
return FALSE;
}
strncpy(m_pSet->m_coldatafmt[iCount].name, SqlColName, StringLeng);
m_pSet->m_coldatafmt[iCount].name[StringLeng] = 0;
m_retcode = SQLColAttribute(m_hstmt, ((SQLUSMALLINT)iCount) + 1, SQL_DESC_TYPE, NULL, 0, NULL, (SQLPOINTER)&SqlType);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT,"取类型代码时失败");
return FALSE;
}
cType = GetDefaultCType(SqlType);
m_pSet->m_coldatafmt[iCount].datatype = cType;
dataLen = GetColLength(m_hstmt, SqlType,iCount+1) ;
m_pSet->m_coldatafmt[iCount].maxlength = dataLen + 1;
m_pSet->m_coldata[iCount].valuelen = new long;
m_pSet->m_coldata[iCount].value = new char[dataLen+1];
if( m_pSet->m_coldata[iCount].value == NULL || m_pSet->m_coldata[iCount].valuelen == NULL)
{
DEBUGINFO("fail: new char[]");
delete m_pSet->m_coldata[iCount].value;
delete m_pSet->m_coldata[iCount].valuelen;
delete m_pSet->m_coldata;
delete m_pSet->m_coldatafmt;
m_pSet->m_coldata = 0;
m_pSet->m_coldatafmt = 0;
return FALSE;
}
memset(m_pSet->m_coldata[iCount].value, 0, dataLen+1);
}
//bind
//
for(int i = 0; i < iNumCols; i++)
{
m_retcode = SQLBindCol(m_hstmt, ((SQLUSMALLINT)i)+1,(SQLSMALLINT)m_pSet->m_coldatafmt[i].datatype ,m_pSet->m_coldata[i].value, m_pSet->m_coldatafmt[i].maxlength, (long *)m_pSet->m_coldata[i].valuelen);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
strError.Format("第 %d 列绑定失败,你指定的类型是%d",i + 1, m_pSet->m_coldatafmt[i].datatype);
ReportError(m_hstmt,SQL_HANDLE_STMT, strError);
return FALSE;
}
}
return TRUE;
}
//
BOOL CMyODBC::PrepareSqlEx(const char *cpSql, CODBCSet &rset,int BindNum)
{
CString strWarn, strError;
if(this->m_hstmt != NULL)
{
SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
m_hstmt = NULL;
}
if(this->m_hdbc == NULL)
{
DEBUGINFO("没有连接数据库,请先进行联接!");
return FALSE;
}
m_retcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hdbc, SQL_HANDLE_DBC,"分配语句句柄失败,不能执行");
return FALSE;
}
this->m_pSet = &rset;
if(!m_pSet->IsEmpty())
{
m_pSet->Empty();
}
m_retcode = SQLExecDirect(m_hstmt, (unsigned char *)cpSql, SQL_NTS);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT, "执行sql语句失败");
SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
m_hstmt = NULL;
return FALSE;
}
SQLSMALLINT iNumCols = BindNum;
/*
m_retcode = SQLNumResultCols(m_hstmt, &iNumCols);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT, "取列数失败,不能执行");
return FALSE;
}
*/
m_pSet->m_cols = iNumCols;
m_pSet->m_coldata = new COL_DATA_ODBC[iNumCols];
if (m_pSet->m_coldata == NULL)
{
DEBUGINFO("分配每个列内存空间失败\n");
return FALSE;
}
m_pSet->m_coldatafmt = new COL_DATAFMT_ODBC[iNumCols];
if(m_pSet->m_coldatafmt == NULL)
{
DEBUGINFO("分配每个列信息的内存空间失败\n");
delete []m_pSet->m_coldata;
m_pSet->m_coldata = 0;
return FALSE;
}
SQLINTEGER dataLen;
SQLSMALLINT SqlType, cType;
char SqlColName[100];
SQLSMALLINT StringLeng;
SqlType = SQL_INTEGER ;
for(int iCount = 0; iCount <iNumCols; iCount++)
{
m_retcode = SQLColAttribute(m_hstmt, ((SQLUSMALLINT)iCount) + 1, SQL_DESC_NAME, (SQLPOINTER)SqlColName, 100, &StringLeng, 0);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT,"取列名时失败");
return FALSE;
}
strncpy(m_pSet->m_coldatafmt[iCount].name, SqlColName, StringLeng);
m_pSet->m_coldatafmt[iCount].name[StringLeng] = 0;
m_retcode = SQLColAttribute(m_hstmt, ((SQLUSMALLINT)iCount) + 1, SQL_DESC_TYPE, NULL, 0, NULL, (SQLPOINTER)&SqlType);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
ReportError(m_hstmt,SQL_HANDLE_STMT,"取类型代码时失败");
return FALSE;
}
cType = GetDefaultCType(SqlType);
m_pSet->m_coldatafmt[iCount].datatype = cType;
dataLen = GetColLength(m_hstmt, SqlType,iCount+1) ;
m_pSet->m_coldatafmt[iCount].maxlength = dataLen + 1;
m_pSet->m_coldata[iCount].valuelen = new long;
m_pSet->m_coldata[iCount].value = new char[dataLen+1];
if( m_pSet->m_coldata[iCount].value == NULL || m_pSet->m_coldata[iCount].valuelen == NULL)
{
DEBUGINFO("fail: new char[]");
delete m_pSet->m_coldata[iCount].value;
delete m_pSet->m_coldata[iCount].valuelen;
delete m_pSet->m_coldata;
delete m_pSet->m_coldatafmt;
m_pSet->m_coldata = 0;
m_pSet->m_coldatafmt = 0;
return FALSE;
}
memset(m_pSet->m_coldata[iCount].value, 0, dataLen+1);
}
//
for(int i = 0; i < iNumCols; i++)
{
m_retcode = SQLBindCol(m_hstmt, ((SQLUSMALLINT)i)+1,(SQLSMALLINT)m_pSet->m_coldatafmt[i].datatype ,m_pSet->m_coldata[i].value, m_pSet->m_coldatafmt[i].maxlength, (long *)m_pSet->m_coldata[i].valuelen);
if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
{
strError.Format("第 %d 列绑定失败,你指定的类型是%d",i + 1, m_pSet->m_coldatafmt[i].datatype);
ReportError(m_hstmt,SQL_HANDLE_STMT, strError);
return FALSE;
}
}
return TRUE;
}
BOOL CMyODBC::FetchData()
{
// __try{
if((m_retcode = SQLFetch(m_hstmt)) != SQL_NO_DATA)
{
ConvertDataToChar();
return TRUE;
}
else
{
if(m_hstmt != NULL)
{
SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
m_hstmt = NULL;
}
return FALSE;
}
// }
// __except(EXCEPTION_EXECUTE_HANDLER)
// {
// return FALSE;
// }
}
//iColumnIndex用来表示列的序号,从1开始计数
SQLSMALLINT CMyODBC::GetDefaultCType(long iODBCType)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -