#include <TChar.h> 
#include <stdio.h> 
#include <stdlib.h> 
#pragma warning (disable:4251) 
#pragma warning (disable:4313) 
// 配置数据源必须头文件 
#include <odbcinst.h> 
/*---------------------------------------------------------------------------*/ 
/*-------------------------- OracleDataBaseCtrl.h ---------------------------*/ 
/*---------------------------------------------------------------------------*/ 
/* 
模块名称:OracleDataBaseCtrl.dll 
版    本:0.1 Alpha 
版    权: 
模块功能:Oracle 数据库操作类 
作    者:wlzqi 
作者邮箱:
mailto:wlzqin@sina.com
	建立时间:2006年7月3日 
最后修改:by wlzqi 2006年7月4日 
修改历程: 
注意事项:1.支持 UNICODE、ANSI 编码 
    2.当使用 get_collect_value 方法时,如果返回值是 NULL 则会发生异常,请注意处理。 
备  注: 测试环境 WinXp + Vc 2003 
使用举例: 
  ★// 定义对象 
  COracleDataBaseCtrl m_OracleDataBase; 
  ★// 1.打开数据库 
  m_OracleDataBase.open_database(数据库MDB文件路径, 用户名, 密码);   // 如没有用户名和密码可以不写 
  ★// 2.关闭数据库 
  m_OracleDataBase.close_database(); 
  ★// 3.打开数据库表 
  // m_OracleDataBase.open_table(表名); 
  ★// 4.删除表 
  m_OracleDataBase.del_table(表名); 
  ★// 5.关闭数据库表 
  m_OracleDataBase.close_table(); 
  ★// 6.遍历数据库表 
  PTSTR ptTableName; 
  for (bool bfOk = m_OracleDataBase.first_table_name(ptTableName); bfOk; bfOk = m_OracleDataBase.next_table_name(ptTableName)) { 
   if (lstrcmp(ptTableName, _TEXT(\\\"\\\")) == 0) continue; 
   // 得到表名 
   MessageBox(ptTableName); 
  } 
  ★// 7.添加字段 
  m_OracleDataBase.add_field(表名, 字段);  // 字段形式 _TEXT(\\\"Field1 INTEGER, Field2 INTEGER, ...\\\") 
  ★// 8.删除字段 
  m_OracleDataBase.del_field(表名, 字段名); 
  ★// 9.获取字段数量 
  int nFieldCount = m_OracleDataBase.get_field_count(表名); 
  ★// 10.遍历字段 
  for (int i = 0; i < nFieldCount; i++) { 
   PCTSTR pctFieldName = m_OracleDataBase.get_field_name(i, 表名); 
   MessageBox(pctFieldName); 
  } 
  ★// 11.获取字段类型 
  DataTypeEnum FieldType; 
  m_OracleDataBase.get_field_type(字段号, FieldType);  // 字段号:字段的序号(从 0 开始) 
  ★// 12.执行 SQL 语句 
  m_OracleDataBase.execute_sql(SQL 语句); 
  ★// 13.获取数据库内容 
  m_OracleDataBase.execute_sql(_TEXT(\\\"SELECT * FROM 表名\\\"));  // 查询所有数据 
  m_OracleDataBase.execute_sql(_TEXT(\\\"SELECT COUNT(*) FROM 表名\\\"));  // 得到数据库记录条数 
  _variant_t vtItemCount = m_OracleDataBase.get_collect_value(long(0)); 
  _bstr_t bsValue = vtItemCount;  // 将结果格式化为字符串 
  ★// 14.遍历数据库所有内容 
  TCHAR szSQL[MAX_PATH]; 
  _stprintf(szSQL, _TEXT(\\\"SELECT * FROM %s\\\"), ptTableName);  // 格式化 SQL 语句 
  m_OracleDataBase.execute_sql(szSQL);   // 执行 SQL 语句 
  m_OracleDataBase.first();  // 将游标移动到第一条数据 
  _bstr_t bsValue; 
  for (int i = 0; i < vtItemCount.intVal; i++) {    // 循环所用行 
   if (m_OracleDataBase.Is_BOF() == 1) break;   // 如到了表最后则退出循环 
   for (int j = 0; j < nFieldCount; j++) {   // 循环所有列 
    variant_t vtValue = m_OracleDataBase.get_collect_value(long(j));  // 格式化得到的每列数据为字符串 
    bsValue = _bstr_t(vtValue.vt == VT_NULL ? _TEXT(\\\"\\\") : vtValue.vt); 
   } 
   bfOk = m_AccessDataBaseCtrl.next();   // 移动到下一列 
  } 
  ★// 15.删除当前行 
  m_OracleDataBase.del_collect_value(); 
  ★// 16.注册数据库 
  COracleDataBaseCtrl::Configuration_DataBaseSource(DNS, 数据库DB文件路径, 描述); 
  ★// 17.其它还有一些请参:OracleDataBaseCtrl.h 文件 
  ★// 18.反注册 COM   CoUninitialize(); 
*/ 
#pragma once 
#pragma warning(disable:4146) 
#import \\\"c:\\\\Program Files\\\\Common Files\\\\System\\\\ado\\\\Msado15.dll\\\" \\\\ 
no_namespace \\\\ 
rename (_TEXT(\\\"EOF\\\"), _TEXT(\\\"adoEOF\\\")) 
#pragma warning(default:4146 )     
#ifdef ORACLEDATABASECTRL_EXPORTS 
#define ORACLEDATABASECTRL_API __declspec(dllexport) 
#else 
#define ORACLEDATABASECTRL_API __declspec(dllimport) 
#endif   
// 此类是从 OracleDataBaseCtrl.dll 导出的 
class ORACLEDATABASECTRL_API COracleDataBaseCtrl { 
public: 
 COracleDataBaseCtrl(void); 
 // TODO: 在此添加您的方法。 
 ~COracleDataBaseCtrl(); 
 //**************************************************************************** 
private: 
 _ConnectionPtr m_pConnection; 
 _RecordsetPtr m_pRecordset; 
 HRESULT hr; 
 //**************************************************************************** 
public: 
 // 打开数据库 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT open_database(PCTSTR pctsUser, PCTSTR pctsPass, PCTSTR pctsServer, long Options = adModeUnknown); 
 // 断开数据库 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT close_database(); 
 //**************************************************************************** 
 // 打开表 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT open_table(PCTSTR pctsTableName, long Options = adCmdText); 
 // 关闭表 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT close_table(); 
 // 创建表创建表和字段 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT create_table(PCTSTR pctsTableName, PCTSTR pctsField, long Options = adCmdText); 
 // 删除表 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT del_table(PCTSTR pctsTableName, long Options = adCmdText); 
 // 添加字段 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT add_field(PCTSTR pctsTableName, PCTSTR pctsField, long Options = adCmdText); 
 // 删除字段 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT del_field(PCTSTR pctsTableName, PCTSTR pctsFieldName, long Options = adCmdText); 
 // 得到表的字段数量 
 unsigned long get_field_count(PCTSTR pctsTableName); 
 // 得到表的字段名 
 PCTSTR get_field_name(unsigned long unFieldIndex, PCTSTR pctsTableName); 
 // 得到字段的类型 
 // 参数:pFieldType [OUT] 字段类型 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT get_field_type(unsigned long unFieldIndex, DataTypeEnum &FieldType); 
 // 遍历所有表名(第一个) 
 // 参数:ptTableName [OUT]  遍历到的表名 
 // 注意:if (lstrcmp(ptTableName, _TEXT(\\\"\\\")) != 0 ) 表名才有效 
 // 返回:false 出错或遍历完毕 
 bool first_table_name(PTSTR &ptsTableName); 
 // 遍历所有表名(下一个) 
 // 参数:ptTableName [OUT]  遍历到的表名 
 // 注意:if (lstrcmp(ptTableName, _TEXT(\\\"\\\")) != 0 ) 表名才有效 
 // 返回:false 出错或遍历完毕 
 bool next_table_name(PTSTR &ptsTableName); 
 //**************************************************************************** 
 // 执行 SQL 语句 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT execute_sql(PCTSTR pctsSQL, long Options = adCmdText); 
 // 是否到记录集末端(0--没有,1--是 -1--错误) 
 int Is_BOF(void); 
 // 跳向前一个记录 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT prev(void); 
 // 遍历到第一个记录 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT first(void); 
 // 遍历到下个记录 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT next(void); 
 // 遍历到最后一个记录 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT last(void); 
 // 更新(确认)记录 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT update(void); 
 // 重新查询 
 // 用 SUCCEEDED 或 FAILED 判断返回值 
 HRESULT reQuery(long Options = 0); 
 // 记录集是否为空(0--没有,1--是 -1--错误) 
 int Is_Empty(void); 
 // 获取数据 
 _variant_t get_collect_value(PCTSTR pctsCollectName); 
 // 获取数据 
 _variant_t get_collect_value(long lCollectIndex); 
 // 设置数据 
 bool put_collect_value(PCTSTR pctsCollectName, _variant_t vtValue); 
 // 设置数据 
 bool put_collect_value(long lCollectIndex, _variant_t vtValue); 
 // 删除一行数据(当前) 
 bool del_collect_value(); 
 //**************************************************************************** 
 // 配置数据源 
 static bool Configuration_DataBaseSource(PCTSTR pctDNS, PCTSTR pctDBPath, PCTSTR pctDescription); 
}; 
/*---------------------------------------------------------------------------*/ 
/*-----------------------End OracleDataBaseCtrl.h ---------------------------*/ 
/*---------------------------------------------------------------------------*/     
/*---------------------------------------------------------------------------*/ 
/*------------------------ OracleDataBaseCtrl.cpp ---------------------------*/ 
/*---------------------------------------------------------------------------*/ 
// OracleDataBaseCtrl.cpp : 定义 DLL 应用程序的入口点。 
// 
#include \\\"stdafx.h\\\" 
#include \\\"OracleDataBaseCtrl.h\\\" 
//**************************************************************************** 
// 数据库表名 
TCHAR * pszTableName; 
// 数据库字段名 
TCHAR * pszFieldName; 
//**************************************************************************** 
COracleDataBaseCtrl::COracleDataBaseCtrl() 
: m_pConnection(NULL) 
, m_pRecordset(NULL) 
, hr(NULL) 
{ 
 // 初始化COM 
 if(FAILED(::CoInitialize(NULL))) return; 
 pszTableName = (TCHAR *)malloc(MAX_PATH); 
 if (pszTableName == NULL) return; 
 pszFieldName = (TCHAR *)malloc(MAX_PATH); 
 if (pszFieldName == NULL) return; 
} 
COracleDataBaseCtrl::~COracleDataBaseCtrl() 
{ 
 // 反注册COM 
 CoUninitialize(); 
 if (pszTableName != NULL) free(pszTableName); 
 if (pszFieldName != NULL) free(pszFieldName); 
}