当前位置: 首页 > 工具软件 > unixODBC > 使用案例 >

对UNIXODBC的封装

凌俊名
2023-12-01

本代码可以任意转载使用,但请保留出处

//blog.csdn.net/bat603

//by ben

//

//.h

 /*
AUTHOR: lizp
MSN:lizp.net@gmail.com

URL:blog.csdn.net/bat603
Description:使用UNIXODBC主页中教程的使用方法,对UnixODBC进行了封装,并增加了锁功能,使用起来非常方便

*/

#ifndef _CPP_ODBC_H_
#define _CPP_ODBC_H_

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>

//查询的最大字段数量
#define FIELD_NUM 1024

class CppODBC
{
public:
 CppODBC( );
 virtual ~CppODBC( );
//公共接口
public:
 bool  Open( );
 bool  Close( );
 bool   Connect( const char* pszDSN, const char* pszUName, const char* pszUPasswd );
 bool   DisConnect( );
 bool   Clear( );
 unsigned int  SQLQuery( const char* pszSQL );
 unsigned int SQLExec( const char* pszSQL );
 unsigned int  SQLExecAutoID( char *pszSQL );
 bool    IsOpen( );
 //查询的结果数量,更新时返回更新的记录数量,删除时返回删除的数量
 unsigned int   GetCount( );
 //返回查询结果的列数两
 unsigned int   GetColumns( );
 int     GetIntValue( unsigned int uiIndex );
 char *     GetStrValue( unsigned int uiIndex );
 //取消操作
     bool       Cancel( );
 //获取错误代码
 unsigned int   GetError( );
 //下一个
 bool       Next( );
 bool   Eof( );
 
 void    Lock();
 void    UnLock();

private:
 SQLHENV     V_OD_Env_;    // Handle ODBC environment 存放环境变量
 SQLHDBC     V_OD_hdbc_;    // Handle connection 连接句柄
 SQLHSTMT     V_OD_hstmt_;   // SQL语句的句柄
 SQLINTEGER    V_OD_rowanz_;   // 操作影响的记录数量
 SQLSMALLINT   V_OD_colanz_;   // 操作影响的记录包含的字段数量
 char*    pszField_[FIELD_NUM];  // 存放一条查询结果集,缓冲区根据查询结果创建
 int     nMaxFiledLen_;    //字段的最大值
 bool     bOpened_;
 bool    bConnected_;
 bool     bEof_;
 
 pthread_mutex_t  mutex_;
 bool     mutex_inited_;
};

#endif


//.cpp

/**********************************************
g++ CppODBC.cpp  -lodbc -g -o CppODBC

//blog.csdn.net/bat603

//by ben
**********************************************/
#include "CppODBC.h"
#include <string.h>


CppODBC::CppODBC( )
{
 bOpened_ = false;
 bConnected_ = false; 
 nMaxFiledLen_ = 512;
 bEof_ = false;

 for(int i=0; i<FIELD_NUM; i++)
  pszField_[i] = NULL;
 
 mutex_inited_ = false;
}

CppODBC::~CppODBC( )
{
 if (mutex_inited_)
  pthread_mutex_destroy(&mutex_);
 
 Clear( );
}
 
bool  CppODBC::Open( )
{
 if ( bOpened_ )//已经打开了
  return true;
  
 long     V_OD_erg; // result of functions 存放错误代码
 
 // allocate Environment handle and register version
 V_OD_erg = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &V_OD_Env_ );
 if ( (V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO) )
 {
  printf("Error AllocHandle/n");
  return false;
 }
 
 V_OD_erg = SQLSetEnvAttr( V_OD_Env_, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0 );
 if ( (V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO) )
 {
  printf("Error SetEnv/n");
  SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env_);
  return false;
 }
 
 //初始化互斥体
 if ( !mutex_inited_ )
 {
  pthread_mutex_init(&mutex_, NULL);
  mutex_inited_ = true;
 }
 
 bOpened_ = true;
 return true;
}

bool  CppODBC::Close( )
{
 if ( bConnected_ )
  return false;
  
 SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env_);
 bOpened_ = false;
 
 return true;
}

bool   CppODBC::Connect( const char* pszDSN, const char* pszUName, const char* pszUPasswd )
{
 if ( !bOpened_ )
  return false;
  
 if ( pszDSN == NULL )
  return false;
  
 long   V_OD_erg = 0;
 SQLCHAR   V_OD_stat[64]= {0}; // Status SQL 执行sql语句的结果状态
 SQLINTEGER  V_OD_err = 0;  // sql语句执行后的错误代码
 SQLSMALLINT  V_OD_mlen = 0;  // 错误返回的消息文本大小
 SQLCHAR         V_OD_msg[256] = {0};// 错误消息缓冲区
 
 // allocate connection handle, set timeout
 V_OD_erg = SQLAllocHandle( SQL_HANDLE_DBC, V_OD_Env_, &V_OD_hdbc_ );
 if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
 {
  printf("Error AllocHDB %d/n",V_OD_erg);
  return false;
 }
 
 //(SQLPOINTER *)
 V_OD_erg = SQLSetConnectAttr(V_OD_hdbc_, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
 if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
 {
  printf("Error SQLSetConnectAttr %d/n",V_OD_erg);
  SQLFreeHandle( SQL_HANDLE_DBC, V_OD_hdbc_ );
  return false;
 }
 
 // Connect to the datasource
 //MysqlODBC //MyPostgres // mysqlitedb
 V_OD_erg = SQLConnect(V_OD_hdbc_, (SQLCHAR*) pszDSN, SQL_NTS,
                                     (SQLCHAR*) pszUName, SQL_NTS,
                                     (SQLCHAR*) pszUPasswd, SQL_NTS);
 if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
 {
  printf("Error SQLConnect %d/n",V_OD_erg);
  SQLGetDiagRec( SQL_HANDLE_DBC, V_OD_hdbc_, 1,
                V_OD_stat, &V_OD_err, V_OD_msg, 256, &V_OD_mlen );
  printf("%s (%d)/n",V_OD_msg, V_OD_err);
  SQLFreeHandle( SQL_HANDLE_DBC, V_OD_hdbc_ );
  return false;
 }
 
 printf("Connected !/n");
 
 V_OD_erg = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc_ , &V_OD_hstmt_);
 if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
 {
  printf("Fehler im AllocStatement %d/n",V_OD_erg);
  SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc_, 1, V_OD_stat, &V_OD_err, V_OD_msg, 256, &V_OD_mlen);
  printf("%s (%d)/n", V_OD_msg, V_OD_err);
  SQLDisconnect( V_OD_hdbc_ );
  SQLFreeHandle( SQL_HANDLE_DBC, V_OD_hdbc_ );
  return false;
 }
 
 bConnected_ = true;
 return true;
}

bool   CppODBC::DisConnect( )
{
 if ( bConnected_ )
 {
  SQLFreeHandle( SQL_HANDLE_STMT,V_OD_hstmt_ );
     SQLDisconnect( V_OD_hdbc_ );
  SQLFreeHandle( SQL_HANDLE_DBC, V_OD_hdbc_ );
  bConnected_ = false;
 }
 
 return true;
}

unsigned int  CppODBC::SQLQuery( const char* pszSQL )
{
 if ( pszSQL == NULL )
  return 0;
  
 long   V_OD_erg = 0;
 SQLCHAR   V_OD_stat[64]= {0}; // Status SQL 执行sql语句的结果状态
 SQLINTEGER  V_OD_err = 0;  // sql语句执行后的错误代码
 SQLSMALLINT  V_OD_mlen = 0;  // 错误返回的消息文本大小
 SQLCHAR         V_OD_msg[256] = {0};// 错误消息缓冲区
 char*   pszBuf = NULL;

  //清空缓冲区
     Clear();
 //查询
 
    V_OD_erg=SQLExecDirect(V_OD_hstmt_, (SQLCHAR*)pszSQL, SQL_NTS);  
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
       printf("Error in Select %d/n", V_OD_erg);
       SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc_, 1, V_OD_stat, &V_OD_err, V_OD_msg, 256, &V_OD_mlen);
       printf("%s (%d)/n",V_OD_msg, V_OD_err);
       return 0;
    }
   
        //获取查询结果的数量
    V_OD_erg = SQLRowCount(V_OD_hstmt_, &V_OD_rowanz_);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
       return 0;
    }
   
    if ( V_OD_rowanz_ == 0 )//没有查询结果     
     return 0;
   
    //获取结果字段的数量
    V_OD_erg=SQLNumResultCols(V_OD_hstmt_, &V_OD_colanz_);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
  return 0;
    }
    printf("Number of Columns %d/n",V_OD_colanz_);
     
    //绑定字段缓冲区
    for ( int i=0; i<V_OD_colanz_; i++ )
    {
     pszBuf = new char[ nMaxFiledLen_+ 1 ];
     memset( pszBuf, 0, nMaxFiledLen_ );
     pszField_[ i ] = pszBuf;
     SQLBindCol(V_OD_hstmt_, i+1, SQL_C_CHAR, pszBuf, nMaxFiledLen_, &V_OD_err);
    }
  
    //得到一行结果,结果放在绑定的缓冲区里面
    V_OD_erg = SQLFetch( V_OD_hstmt_ );
    if ( V_OD_erg != SQL_NO_DATA )
     bEof_ = false;
     
    return V_OD_rowanz_;
}

bool   CppODBC::Clear( )
{
 V_OD_rowanz_ = 0;
 V_OD_colanz_ = 0;
 bEof_ = true;
 for (int i=0; i<FIELD_NUM; i++)
 {
  if ( pszField_[i] != NULL )
   delete  [] pszField_[i];
  pszField_[i] = NULL;
 }
 return true;
}

unsigned int  CppODBC::SQLExec( const char* pszSQL )
{
 if ( pszSQL == NULL )
  return 0;
  
 long   V_OD_erg = 0;
 SQLCHAR   V_OD_stat[64]= {0}; // Status SQL 执行sql语句的结果状态
 SQLINTEGER  V_OD_err = 0;  // sql语句执行后的错误代码
 SQLSMALLINT  V_OD_mlen = 0;  // 错误返回的消息文本大小
 SQLCHAR         V_OD_msg[256] = {0};// 错误消息缓冲区
 char*   pszBuf = NULL;

  //清空缓冲区
    Clear();
 
    V_OD_erg=SQLExecDirect(V_OD_hstmt_, (SQLCHAR*)pszSQL, SQL_NTS);  
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
       printf("Error in Select %d/n", V_OD_erg);
       SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc_, 1, V_OD_stat, &V_OD_err, V_OD_msg, 256, &V_OD_mlen);
       printf("%s (%d)/n",V_OD_msg, V_OD_err);
       return 0;
    }
   
    //获取查询结果的数量
    V_OD_erg = SQLRowCount(V_OD_hstmt_, &V_OD_rowanz_);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
       return 0;
    }
      
    return V_OD_rowanz_;
}

unsigned int  CppODBC::SQLExecAutoID( char *pszSQL )
{

if ( pszSQL == NULL || pszIdField == NULL )
        return 0;
       
    //不同的数据库处理方法不同
    //通用办法比较笨,需要增加自动增长字段的名字作为参数
    unsigned long ulIdentiy = 0;
   
    ulIdentiy = SQLExec( pszSQL );
    if ( ulIdentiy == 0 )
        return 0;

    //获取插入操作的数据表   
    string str = pszSQL;

    transform(str.begin(), str.end(), str.begin(), toupper); 
    int nLen1 = str.find("INTO");
    int nLen2 = str.find("VALUES");

    str = pszSQL;
    nLen1 += strlen("INTO");
    string str1 = str.substr(nLen1, nLen2-nLen1);
    nLen1 = 0;
    nLen1 = str1.find("(", 0);//从开始寻找左括号
    if ( nLen1 > 0 )
        str1 = str1.substr(0, nLen1);//消除带括号部分
   
    str = "SELECT MAX(";
    str += pszIdField;
    str += ") FROM ";
    str += str1;
   
    ulIdentiy = SQLQuery(str.c_str());
    ulIdentiy = GetIntValue(0);
   
    return ulIdentiy;

}

bool    CppODBC::IsOpen( )
{
 return bOpened_;
}

//查询的结果数量,更新时返回更新的记录数量,删除时返回删除的数量
unsigned int   CppODBC::GetCount( )
{
 return V_OD_rowanz_;
}

//返回查询结果的列数两
unsigned int   CppODBC::GetColumns( )
{
 return V_OD_colanz_;
}

int   CppODBC::GetIntValue( unsigned int uiIndex )
{
 if ( uiIndex < 0 || uiIndex > V_OD_colanz_ )
  return 0;
  
 int nField = 0;
     if (pszField_[uiIndex] != NULL)
        nField = atoi( pszField_[uiIndex] );
 nField = atoi( pszField_[uiIndex] );
 
 return nField; 
}

char *     CppODBC::GetStrValue( unsigned int uiIndex )
{
 if ( uiIndex < 0 || uiIndex > V_OD_colanz_ )
  return NULL;
 
 return pszField_[uiIndex];
}

//取消操作
bool       CppODBC::Cancel( )
{

}

//获取错误代码
unsigned int   CppODBC::GetError( )
{

}

//下一个
bool       CppODBC::Next( )
{
 long V_OD_erg = 0;
 
 V_OD_erg = SQLFetch( V_OD_hstmt_ );
    if ( V_OD_erg != SQL_NO_DATA )
     bEof_ = false;
    else
     bEof_ = true;
   
    return !bEof_;    
}

bool   CppODBC::Eof( )
{
 return bEof_;
}

void    CppODBC::Lock()
{
 if (!mutex_inited_)
  return ;

 pthread_mutex_lock(&mutex_);
}

void    CppODBC::UnLock()
{
 if (!mutex_inited_)
  return ;

 pthread_mutex_unlock(&mutex_);
}


int main()
{
 CppODBC cppOdbc;
 
 bool bRes = cppOdbc.Open();
 if ( !bRes )
 {
  printf ( "Open error!/n " );
  return 0;
 }
 printf ( "Open OK!/n " );
 bRes = cppOdbc.Connect("mysqlODBC",  "lizp" ,  "lizp");
 if ( !bRes )
 {
  printf ( "Connect error!/n " );
  return 0;
 }

 printf ( "Connect OK!/n " );
 int nRes = 0;

 //INSERT INTO UserInfo VALUES('44', 'ODBCTest22')
 nRes = cppOdbc.SQLExec( "UPDATE UserInfo SET UID='55' WHERE UID='44'" );

 printf ( "SQLExec the nRes is %d/n", nRes );

 nRes = cppOdbc.SQLQuery("SELECT UID,UName FROM UserInfo");
 printf ( "SQLQuery the nRes is %d/n", nRes );
 
 char *pszBuf = NULL;
 int  nBuf = 0;
 int  i = 0;
 while( !cppOdbc.Eof() )
 {
  i = 0;
  nBuf = cppOdbc.GetIntValue( i++ );
  printf ( " UID is %d/n", nBuf );

  //nBuf = cppOdbc.GetIntValue( i++ );
  //printf ( " UID is %d/n", nBuf );
  
  pszBuf = cppOdbc.GetStrValue( i++ );
  printf ( " UName is %s/n", pszBuf );

  cppOdbc.Next();

  //getchar();
 }
 
 cppOdbc.DisConnect();
 cppOdbc.Close();
 
 return 0; 
}


 

 类似资料: