📄 csqlocilibrary.cpp
字号:
#include "CSqlOciLibrary.h"
#include "comlog.h"
#include "sybase_common.h"
#include "CVariant.h"
#include <iostream>
sword g_status ; // 用于 MYCHECK 宏定义
char g_errMsg[10000] ;
int g_error ; // 用于 MYCHECK 宏定义
#define MYCHECK( envhp , status ) \
g_status = status ; \
g_error = checkError( envhp , g_status ) ;\
if ( g_error ) { \
LOG1(NULL , 0 , "error in %d line ", __LINE__ );\
return false ; \
}
#define MYCHECK_NR( envhp , status ) \
g_status = status ; \
g_error = checkError( envhp , g_status ) ;\
if ( g_error ) { \
LOG1(NULL , 0 , "error in %d line ", __LINE__ );\
}
// 对错误进行检查
sb4 g_errcode = 0 ;
static int checkError(OCIError * errhp,sword status)
{
static text errbuf[512];
ub4 buflen;
g_errcode = 0 ;
if ( status == OCI_SUCCESS ) return false ;
switch (status){
case OCI_NEED_DATA:
LOG(NULL , 0 , "Error OCI_NEED_DATA");
break;
case OCI_NO_DATA:
LOG(NULL , 0 , "Error OCI_NO_DATA");
break;
case OCI_SUCCESS_WITH_INFO:
LOG(NULL , 0 , "Error OCI_SUCCESS_WITH_INFO");
break;
case OCI_ERROR:
if(errhp!=NULL){
OCIErrorGet((dvoid *) errhp, (ub4) 1,(text *)NULL,&g_errcode,
errbuf,(sb4)sizeof(errbuf),(ub4)OCI_HTYPE_ERROR);
LOG2(NULL , 0 , "%s errcode %d " , (char *)errbuf,(int)g_errcode);
}
else
LOG(NULL , 0 , "error No Reason");
break;
case OCI_INVALID_HANDLE:
LOG(NULL , 0 , "Error OCI_INVALID_HANDLE");
break;
case OCI_STILL_EXECUTING:
LOG(NULL , 0 , "Error OCI_STILL_EXECUTING");
break;
case OCI_CONTINUE:
LOG(NULL , 0 , "Error OCI_CONTINUE");
break;
default:
break;
}
LOG1(NULL , 0 , "SQL ERR:%s" , g_errMsg ) ;
return ( true );
}
CORACLEResult::CORACLEResult (const CORACLEDriver * db):CSqlResult (db)
//CSqlResult类的Oracle实现,以db为驱动
{
sword status;
bool b_error ;
connection = (CORACLEDriver*)db ;
status=OCIHandleAlloc(
(dvoid *)connection->envhp,
(dvoid **)&stmthp,
(ub4)OCI_HTYPE_STMT,
(size_t)0, (dvoid **)0
);
b_error=checkError(NULL,status);
if ( b_error ) m_valid = false ;
else m_valid = true ;
}
CORACLEResult::~CORACLEResult ()
{
// delete column;
sword status;
bool b_error ;
status=OCIHandleFree(stmthp,OCI_HTYPE_STMT);
b_error = checkError(NULL,status);
}
/*================================================================================
** 函数名称: CORACLEResult::bind
** 主要功能: 将输出绑定到内存区
** 入口参数:
** 序号 参数类型 参数名称 作用 说明
** 1 char (*)[] buf 记录内存指针
** 2 int len 记录数组长度
** 3
** 出口参数: 类型: bool 作用:成功返回true 失败返回false
** 修改记录:
=================================================================================== */
bool CORACLEResult::bind (char (*buf)[SYBASE_MAX_COLUMN_LENGTH], int len)
{
return 0 ;
}
/*================================================================================
** 函数名称: CORACLEResult::fetch
** 主要功能: 索取一行数据
** 入口参数: 无
** 序号 参数类型 参数名称 作用 说明
**
** 出口参数: 类型: bool 作用:成功返回true 失败返回false
** 修改记录
=================================================================================== */
bool CORACLEResult::fetch ()
{
bool b_error ;
sword status=OCIStmtFetch(stmthp,errorhp,1,OCI_FETCH_NEXT,OCI_DEFAULT);
if(status==OCI_NO_DATA)
return false;
else if(status==OCI_SUCCESS)
return true;
else
checkError(errorhp,status);
return true;
}
/*================================================================================
** 函数名称: CORACLEResult::data
** 主要功能: 索取请求列的数据
** 入口参数:
** 序号 参数类型 参数名称 作用 说明
** 1 int field 标记列
** 出口参数: 类型: CVariant 作用:返回相应列值的CVariant类型
** 修改记录
=================================================================================== */
CVariant CORACLEResult::data (int columnIndex)
{
static char s_tempbuf[20];
if(columnInfo[columnIndex-1].columnType==CVariant::Int)
{ // 列为number类型
boolean isInt ; // 是否整数
int i_value;
float f_value ;
// 先判断是否整数
OCINumberIsInt ( errorhp , (OCINumber *)(columnInfo[columnIndex-1].data), &isInt );
if (isInt )
{ // 整数
OCINumberToInt(errorhp,(OCINumber *)(columnInfo[columnIndex-1].data),
sizeof(int),OCI_NUMBER_SIGNED,&i_value);
return i_value;
}
else
{ // float
OCINumberToReal(errorhp,(OCINumber *)(columnInfo[columnIndex-1].data),sizeof(float),&f_value);
return f_value ;
}
}
else if(columnInfo[columnIndex-1].columnType==CVariant::Pchar)
{ //是否字符型
OCIEnv * envhp=connection->envhp;
text * strValue=OCIStringPtr(envhp,(OCIString *)(columnInfo[columnIndex-1].data));
return (char *)strValue;
}
else if (columnInfo[columnIndex-1].columnType==CVariant::mydate)
{ // 日期
/*
sb2 year;
ub1 month;
ub1 day;
ub1 hour;
ub1 minute;
ub1 sec;
OCIDateGetDate((OCIDate *)columnInfo[columnIndex-1].data,&year,
&month,&day);
OCIDateGetTime((OCIDate *)columnInfo[columnIndex-1].data,&hour,
&minute,&sec);
return ZcDate(year,month,day, 0 );
*/
ub4 buf_size = 20 ;
OCIDateToText(errorhp , (OCIDate *)columnInfo[columnIndex-1].data ,
(text*)"yyyy-mm-dd hh24:mi:ss" , (ub1)21 , (text*)0 ,
(ub4)0 , &buf_size , (text*)s_tempbuf );
return s_tempbuf ;
}
else
{
LOG(NULL , 0 , "error type or columIndex");
}
return CVariant();
}
char *CORACLEResult::stringData (int columnIndex)
{
static char s_tempbuf[256];
if(columnInfo[columnIndex-1].columnType==CVariant::Pchar)
{
OCIEnv * envhp=connection->envhp;
text * value=OCIStringPtr(envhp,(OCIString *)(columnInfo[columnIndex-1].data));
return (char *)value;
}
else if (columnInfo[columnIndex-1].columnType==CVariant::mydate)
{ // 日期
ub4 buf_size = 30 ;
OCIDateToText(errorhp , (OCIDate *)columnInfo[columnIndex-1].data ,
(text*)"yyyy-mm-dd hh24:mi:ss" , (ub1)21 , (text*)0 ,
(ub4)0 , &buf_size , (text*)s_tempbuf );
return s_tempbuf ;
}
else if(columnInfo[columnIndex-1].columnType==CVariant::Int)
{ // 列为number类型
ub4 buf_size = 30 ;
OCINumberToText(errorhp,(OCINumber *)(columnInfo[columnIndex-1].data),
(text *)"TM",2,NULL,0,&buf_size,(text*)s_tempbuf);
return s_tempbuf ;
}
return NULL ;
}
int CORACLEResult::intData (int columnIndex)
{
if(columnInfo[columnIndex-1].columnType==CVariant::Int)
{
int value;
OCINumberToInt(errorhp,(OCINumber *)(columnInfo[columnIndex-1].data),
sizeof(int),OCI_NUMBER_SIGNED,&value);
return value;
}
else if(columnInfo[columnIndex-1].columnType==CVariant::Pchar)
{
text * value=OCIStringPtr(connection->envhp,
(OCIString *)(columnInfo[columnIndex-1].data));
return atoi((char *)value);
}
return 0 ;
}
/*================================================================================
**说明:此函数在1.0版本未实现,待后续版本
** 函数名称: CORACLEResult::isNull
** 主要功能: 请求列是否为空
**
** 入口参数:
** 序号 参数类型 参数名称 作用 说明
** 1 int field 标记列
** 出口参数:
** 类型: 作用
** bool 为空返回true 否则返回false
**
** 修改记录
=================================================================================== */
bool CORACLEResult::isNull (int field)
{
return ( columnInfo[field-1].ind == -1 ) ;
}
string cutSqlDbName( const string& sql )
{
string s = sql ;
int pos ;
while (( pos = s.find("zcst..")) >0 )
{
s.erase( pos , 6 ) ;
}
while (( pos = s.find("zcdynadb..")) >0 )
{
s.erase( pos , 10 ) ;
}
return s ;
}
bool CORACLEResult::reset (const string & query)
{
int nReturn;
bool b_error;
strcpy( g_errMsg , query.c_str() ) ;
errorhp = connection->errorhp ;
if (!driver ()) //驱动未启动
return false;
if (!driver ()->isOpen () || driver ()->isOpenError ()) //驱动打开且成功
{
return false;
}
setActive (false); //未活动
string sQuery = cutSqlDbName( query ) ;
// 判断是否为select 语句
int pos = 0 ;
const char* str_query = sQuery.c_str();
while ( str_query[pos] )
{
if ( str_query[pos]!=' ' )
{
break ;
}
pos++ ;
}
if(( strncmp( str_query+pos , "select" , 6 ) != 0 ) && ( strncmp( str_query+pos , "SELECT" , 6 ) != 0 ) )
{
// 不是select语句
if (! connection->_exec( sQuery ) )
{
return false ;
}
else
{
setActive (true); //未活动
return true ;
}
}
// 是select语句
sword status;
MYCHECK( errorhp ,
status=OCIStmtPrepare(
stmthp,errorhp,
(text *)sQuery.c_str(),sQuery.length(),
OCI_NTV_SYNTAX,OCI_DEFAULT
));
MYCHECK( errorhp ,
OCIStmtExecute(connection->svcctxhp,stmthp,errorhp,0,0, NULL,NULL,OCI_DEFAULT));
OCIEnv * envhp=connection->envhp;
MYCHECK( errorhp ,
OCIAttrGet(stmthp,OCI_HTYPE_STMT,
&columnCount,0,OCI_ATTR_PARAM_COUNT, errorhp));
columnInfo=new CColumn[columnCount];
text * columnName;
char cTempName[256] ;
ub4 sizep ;
for(int iLoop=0;iLoop<columnCount;iLoop++)
{
OCIParam * param;
OCIDefine * define;
ub2 columnType,columnSize;
MYCHECK( errorhp ,
OCIParamGet(stmthp,OCI_HTYPE_STMT,errorhp,(dvoid **)¶m,
iLoop+1));
MYCHECK( errorhp ,
OCIAttrGet(param,OCI_DTYPE_PARAM,&columnType,0,
OCI_ATTR_DATA_TYPE,errorhp));
MYCHECK( errorhp ,
OCIAttrGet(param,OCI_DTYPE_PARAM,&columnSize,0,
OCI_ATTR_DATA_SIZE,errorhp));
columnInfo[iLoop].columnSize=columnSize;
MYCHECK( errorhp ,
OCIAttrGet(param,OCI_DTYPE_PARAM,&columnName,(ub4*)&sizep,
OCI_ATTR_NAME,errorhp));
strncpy( cTempName , (char*) columnName , (size_t) sizep ) ;
cTempName[sizep]=0 ;
columnInfo[iLoop].columnName=cTempName;
//MYCHECK( errorhp ,
// OCIAttrGet(param,OCI_DTYPE_PARAM,&columnName,0,
// OCI_ATTR_NAME,errorhp));
//columnInfo[iLoop].columnName=string((char *)columnName);
switch(columnType){
case CORACLEDriver::ORAVARCHAR2:
case CORACLEDriver::ORALONG:
case CORACLEDriver::ORARAW:
case CORACLEDriver::ORALANGRAW:
case CORACLEDriver::ORACHAR:
// 字符类型
columnInfo[iLoop].columnType= CVariant::Pchar ;
columnInfo[iLoop].data=NULL;
MYCHECK( errorhp ,
OCIStringResize(envhp,errorhp,columnSize+1,
(OCIString **)&(columnInfo[iLoop].data)));
MYCHECK( errorhp ,
OCIDefineByPos(stmthp,&define,errorhp,iLoop+1,
(OCIString **)&(columnInfo[iLoop].data),
columnSize+1,SQLT_VST,&(columnInfo[iLoop].ind),
&(columnInfo[iLoop].fetchLength),
&(columnInfo[iLoop].retCode),OCI_DEFAULT));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -