本节看看AMPS中对Oracle数据库进行操作的方法,使用的是Oracle的C访问接口OCI,关于OCI各函数的中文说明可参考这篇文章http://www.cnblogs.com/joeblackzqq/archive/2011/04/24/2026461.html
下面看看AMPS中Oracle操作各函数实现:
AMPS_Oracle.h
#ifndef __HEADER_AMPS_DB_ORACLE_H
#define __HEADER_AMPS_DB_ORACLE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "AMPS_Defines.h"
#include "AMPS_LinkList.h"
#include "AMPS_MemMgt.h"
#include "AMPS_EventSystem.h"
#include "AMPS_Core.h"
#include "AMPS_API.h"
typedef struct _OracleContext t_OracleContext;
typedef struct _OracleColumnData t_OracleColumnData;
#define ORACLE_MAX_SELECT_COLUMN_LIST_SIZE 1024
#define ORACLE_MAX_DB_PATH_SIZE 2048
#define ORACLE_SELECT_COUNT_QUERY_SIZE 4096
struct _OracleColumnData
{
unsigned char* puchValue;
signed int nValueLen;
};
#ifdef WIN32
struct _OracleContext
{
OCIEnv* hOCIEnv;
OCIError* hOCIError;
OCIServer* hOCIServer;
OCISvcCtx* hOCISvcCtx;
OCISession* hOCISession;
t_OracleColumnData poOracleColumnData[ORACLE_MAX_SELECT_COLUMN_LIST_SIZE];
unsigned char puchDBPath[ORACLE_MAX_DB_PATH_SIZE];
unsigned char puchSelectCountQuery[ORACLE_SELECT_COUNT_QUERY_SIZE];
};
#endif
int Oracle_Init(void* r_pvAMPSContext, void* r_pvBDEngineContext);
void Oracle_Cleanup(void* r_pvAMPSContext, void* r_pvBDEngineContext);
int Oracle_Query(void* r_pvAMPSContext, void* r_pvBDEngineContext, const char* r_pcchQueryStatement, unsigned long r_ulLengthOfQuery, t_AMPSDBEngineResult* r_poAMPSDBEngineResult);
void Oracle_FreeResults(void* r_pvAMPSContext, void* r_pvBDEngineContext, t_AMPSDBEngineResult* r_poAMPSDBEngineResult);
void Oracle_CheckError(void* r_pvAMPSContext, void* r_pvBDEngineContext, signed int r_nStatus);
int Oracle_GetNumberOfRecords(void* r_pvAMPSContext, void* r_pvBDEngineContext, const char* r_pcchQueryStatement, unsigned long r_ulLengthOfQuery);
#ifdef __cplusplus
}
#endif
#endif //__HEADER_AMPS_DB_ORACLE_H
AMPS_Oracle.c
#include "AMPS_DBEngine.h"
#include "AMPS_Oracle.h"
/*****************************************************************
函数名称: Oracle_Init
功能描述: Oracle数据库访问初始化函数
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvBDEngineContext 数据库应用上下文
出参:
返回值:
int
*****************************************************************/
int Oracle_Init(void* r_pvAMPSContext, void* r_pvBDEngineContext)
{
#ifdef WIN32
signed int nReturnCode = 0;
t_OracleContext* poOracleContext = NULL;
t_BDEngineContext* poBDEngineContext = r_pvBDEngineContext;
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
poOracleContext = (t_OracleContext*)AMPS_InternalMalloc(sizeof(t_OracleContext));
if(NULL == poOracleContext)
{
TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for poOracleContext.\n");
return AMPS_ERROR_FAILURE;
}
poBDEngineContext->poDBHandle = poOracleContext;
/*创建OCI环境*/
//allocate an environment handle
nReturnCode = OCIEnvCreate((OCIEnv**)&poOracleContext->hOCIEnv, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);
if(OCI_SUCCESS != nReturnCode)
{
printf("OCIEnvCreate failed with nReturnCode = %d.\n", nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*分配错误句柄OCIError */
//allocate an error handle
nReturnCode = OCIHandleAlloc((void*)poOracleContext->hOCIEnv, (void**)&poOracleContext->hOCIError, OCI_HTYPE_ERROR, 0, NULL);
if(OCI_SUCCESS != nReturnCode)
{
printf("OCIHandleAlloc failed with nReturnCode = %d.\n", nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*分配服务器句柄OCIServer*/
//allocate a server handle
nReturnCode = OCIHandleAlloc((void*)poOracleContext->hOCIEnv, (void**)&poOracleContext->hOCIServer, OCI_HTYPE_SERVER, 0, NULL);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
//"//192.168.0.4:1521/orcl"
sprintf(poOracleContext->puchDBPath, "//%s:1521/%s", poBDEngineContext->pchHostName, poBDEngineContext->pchDataBaseName);
/*创建多用户连接*/
//create a server context
nReturnCode = OCIServerAttach(poOracleContext->hOCIServer, poOracleContext->hOCIError, (unsigned char*)poOracleContext->puchDBPath, strlen(poOracleContext->puchDBPath), 0);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*分配服务器环境句柄*/
//allocate a service handle
nReturnCode = OCIHandleAlloc((void*)poOracleContext->hOCIEnv, (void**)&poOracleContext->hOCISvcCtx, OCI_HTYPE_SVCCTX, 0, NULL);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*设置句柄OCI_HTYPE_SVCCTX的属性*/
//set the server attribute in the service context handle
nReturnCode = OCIAttrSet((void*)poOracleContext->hOCISvcCtx, OCI_HTYPE_SVCCTX, (void*)poOracleContext->hOCIServer, 0, OCI_ATTR_SERVER, (OCIError*)poOracleContext->hOCIError);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*分配用户会话句柄*/
//allocate a user session handle
nReturnCode = OCIHandleAlloc((void*)poOracleContext->hOCIEnv, (void**)&poOracleContext->hOCISession, OCI_HTYPE_SESSION, 0, NULL);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*设置数据库访问用户名*/
//set username and password attributes in user session handle
nReturnCode = OCIAttrSet((void*)poOracleContext->hOCISession, OCI_HTYPE_SESSION, (void*)poBDEngineContext->pchUserName, strlen((char*)poBDEngineContext->pchUserName), OCI_ATTR_USERNAME, poOracleContext->hOCIError);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*设置数据库访问密码*/
nReturnCode = OCIAttrSet((void*)poOracleContext->hOCISession, OCI_HTYPE_SESSION, (void*)poBDEngineContext->pchPassword, strlen((char*)poBDEngineContext->pchPassword), OCI_ATTR_PASSWORD, poOracleContext->hOCIError);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*认证用户并建立连接*/
//start the session
nReturnCode = OCISessionBegin (poOracleContext->hOCISvcCtx, poOracleContext->hOCIError, poOracleContext->hOCISession, OCI_CRED_RDBMS, OCI_DEFAULT);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*设置用户属性*/
//set the user session attribute in the service context handle
nReturnCode = OCIAttrSet(poOracleContext->hOCISvcCtx, OCI_HTYPE_SVCCTX, poOracleContext->hOCISession, sizeof(OCISession*), OCI_ATTR_SESSION, poOracleContext->hOCIError);
if(OCI_SUCCESS != nReturnCode)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
return AMPS_SUCCESS;
#else
return AMPS_ERROR_FAILURE;
#endif
}
/*****************************************************************
函数名称: Oracle_Cleanup
功能描述: Oracle数据库访问销毁函数
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvBDEngineContext 数据库应用上下文
出参:
返回值:
int
*****************************************************************/
void Oracle_Cleanup(void* r_pvAMPSContext, void* r_pvBDEngineContext)
{
#ifdef WIN32
t_BDEngineContext* poBDEngineContext = r_pvBDEngineContext;
t_OracleContext* poOracleContext = poBDEngineContext->poDBHandle;
if(poOracleContext->hOCIEnv)
{
(void)OCIHandleFree((void*)poOracleContext->hOCIEnv, OCI_HTYPE_ENV);
}
#endif
}
/*****************************************************************
函数名称: Oracle_GetNumberOfRecords
功能描述: 获取记录条数
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvBDEngineContext 数据库应用上下文
const char* r_pcchQueryStatement SQL查询语句
unsigned long r_ulLengthOfQuery SQL查询语句长度
出参:
返回值:
int
*****************************************************************/
int Oracle_GetNumberOfRecords(void* r_pvAMPSContext, void* r_pvBDEngineContext, const char* r_pcchQueryStatement, unsigned long r_ulLengthOfQuery)
{
#ifdef WIN32
t_BDEngineContext* poBDEngineContext = r_pvBDEngineContext;
t_OracleContext* poOracleContext = poBDEngineContext->poDBHandle;
signed int nReturnCode = OCI_ERROR;
OCIStmt* hOCIStmtSelectCount = NULL;
unsigned long ulLengthOfSelectCountQuery = 0;
const char* pchPosition = NULL;
OCIDefine* hOCIDefine = NULL;
OCIParam* hOCIParam = NULL;
unsigned int unSize = 0;
unsigned int unNoOfColumns = 0;
unsigned int unColumnCount = 0;
unsigned int unRowCount = 0;
t_AMPSDBEngineResult oAMPSDBEngineResult;
/*查看SQL语句中是否有FROM关键字*/
pchPosition = SAPI_StrCaseStr(r_pcchQueryStatement, "FROM");
if(NULL == pchPosition)
{
return AMPS_ERROR_FAILURE;
}
memset(poOracleContext->puchSelectCountQuery, 0, ORACLE_SELECT_COUNT_QUERY_SIZE);
sprintf(poOracleContext->puchSelectCountQuery, "Select Count(*) %s", pchPosition);
/*创建语句句柄*/
//allocate statement handle
nReturnCode = OCIHandleAlloc(poOracleContext->hOCIEnv, (void**)&hOCIStmtSelectCount, OCI_HTYPE_STMT, 0, NULL);
if(nReturnCode == OCI_SUCCESS)
{
ulLengthOfSelectCountQuery = strlen(poOracleContext->puchSelectCountQuery);
/*准备SQL语句*/
nReturnCode = OCIStmtPrepare(hOCIStmtSelectCount, poOracleContext->hOCIError, (unsigned char*)poOracleContext->puchSelectCountQuery, ulLengthOfSelectCountQuery, OCI_NTV_SYNTAX, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
}
memset(poOracleContext->poOracleColumnData, 0, (sizeof(t_OracleColumnData) * ORACLE_MAX_SELECT_COLUMN_LIST_SIZE));
/*执行SQL语句*/
nReturnCode = OCIStmtExecute(poOracleContext->hOCISvcCtx, hOCIStmtSelectCount, poOracleContext->hOCIError, 0, 0, NULL, NULL, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
/*获取属性*/
nReturnCode = OCIAttrGet(hOCIStmtSelectCount, OCI_HTYPE_STMT, &unNoOfColumns, NULL, OCI_ATTR_PARAM_COUNT, poOracleContext->hOCIError);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
//get next column info
for(unColumnCount = 0; unColumnCount < unNoOfColumns; unColumnCount++)
{
nReturnCode = OCIParamGet(hOCIStmtSelectCount, OCI_HTYPE_STMT, poOracleContext->hOCIError, (void**)&hOCIParam, unColumnCount + 1);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
// maximum data size in bytes
unSize = 0;
nReturnCode = OCIAttrGet(hOCIParam, OCI_DTYPE_PARAM, &unSize, NULL, OCI_ATTR_DATA_SIZE, poOracleContext->hOCIError);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
poOracleContext->poOracleColumnData[unColumnCount].puchValue = AMPS_InternalMalloc(unSize + 1);
poOracleContext->poOracleColumnData[unColumnCount].nValueLen = unSize;
memset(poOracleContext->poOracleColumnData[unColumnCount].puchValue, 0, poOracleContext->poOracleColumnData[unColumnCount].nValueLen);
/*定义输出变量*/
nReturnCode = OCIDefineByPos(hOCIStmtSelectCount, &hOCIDefine, poOracleContext->hOCIError, unColumnCount + 1, poOracleContext->poOracleColumnData[unColumnCount].puchValue, unSize, STRING_TYPE, NULL, NULL, NULL, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
}
oAMPSDBEngineResult.ulNumberOfColumns = unNoOfColumns;
oAMPSDBEngineResult.ulNumberOfRows = 100;
oAMPSDBEngineResult.ulNumberOfResults = oAMPSDBEngineResult.ulNumberOfRows;
if (0 < oAMPSDBEngineResult.ulNumberOfRows)
{
oAMPSDBEngineResult.ppoAMPSDBEngineTable = (t_AMPSDBEngineTable**)AMPS_InternalMalloc(sizeof(t_AMPSDBEngineTable*) * oAMPSDBEngineResult.ulNumberOfRows);
if(NULL == oAMPSDBEngineResult.ppoAMPSDBEngineTable)
{
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for r_poBDEngineResult->ppoAMPSDBEngineTable.\n");
return AMPS_ERROR_FAILURE;
}
//printf("\n\n r_poBDEngineResult->ulNumberOfRows is %ld r_poBDEngineResult->ulNumberOfColumns %ld and r_poBDEngineResult->ppoAMPSDBEngineTable %p\n\n",r_poBDEngineResult->ulNumberOfRows, r_poBDEngineResult->ulNumberOfColumns, r_poBDEngineResult->ppoAMPSDBEngineTable);
for(unRowCount = 0; unRowCount < oAMPSDBEngineResult.ulNumberOfRows; unRowCount++)
{
/*逐行提取结果*/
nReturnCode = OCIStmtFetch(hOCIStmtSelectCount, poOracleContext->hOCIError, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
break;
}
oAMPSDBEngineResult.ppoAMPSDBEngineTable[unRowCount] = (t_AMPSDBEngineTable*)AMPS_InternalMalloc(sizeof(t_AMPSDBEngineTable) * oAMPSDBEngineResult.ulNumberOfColumns);
if(NULL == oAMPSDBEngineResult.ppoAMPSDBEngineTable[unRowCount])
{
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter].\n");
return AMPS_ERROR_FAILURE;
}
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Pointer = %p.\n", r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter]);
for(unColumnCount = 0; unColumnCount < unNoOfColumns; unColumnCount++)
{
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Column %u is %lu bytes in length and value %s.\n", (ulColumnCounter + 1), pulLengthOfField[ulColumnCounter], oMYSQLRow[ulColumnCounter]);
oAMPSDBEngineResult.ppoAMPSDBEngineTable[unRowCount][unColumnCount].pchField = AMPS_InternalMalloc(poOracleContext->poOracleColumnData[unColumnCount].nValueLen);
oAMPSDBEngineResult.ppoAMPSDBEngineTable[unRowCount][unColumnCount].nLengthOfField = poOracleContext->poOracleColumnData[unColumnCount].nValueLen;
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Field Length = %d.\n", r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter][ulColumnCounter].nLengthOfField);
memcpy(oAMPSDBEngineResult.ppoAMPSDBEngineTable[unRowCount][unColumnCount].pchField, poOracleContext->poOracleColumnData[unColumnCount].puchValue, poOracleContext->poOracleColumnData[unColumnCount].nValueLen);
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Filed Value = %s.\n", r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter][ulColumnCounter].pchField);
}
}
oAMPSDBEngineResult.ulNumberOfRows = atoi(oAMPSDBEngineResult.ppoAMPSDBEngineTable[0][0].pchField);
}
if(hOCIParam)
{
//ignore result code
OCIDescriptorFree(hOCIParam, OCI_DTYPE_PARAM);
}
for(unColumnCount = 0; unColumnCount < unNoOfColumns; unColumnCount++)
{
if(NULL != poOracleContext->poOracleColumnData[unColumnCount].puchValue)
{
AMPS_InternalFree(poOracleContext->poOracleColumnData[unColumnCount].puchValue);
poOracleContext->poOracleColumnData[unColumnCount].nValueLen = 0;
}
}
return(oAMPSDBEngineResult.ulNumberOfRows);
#endif
return 0;
}
/*****************************************************************
函数名称: Oracle_Query
功能描述: 执行SQL查询语句
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvBDEngineContext 数据库应用上下文
const char* r_pcchQueryStatement SQL查询语句
unsigned long r_ulLengthOfQuery SQL查询语句长度
t_AMPSDBEngineResult* r_poAMPSDBEngineResult 结果集
出参:
返回值:
int
*****************************************************************/
int Oracle_Query(void* r_pvAMPSContext, void* r_pvBDEngineContext, const char* r_pcchQueryStatement, unsigned long r_ulLengthOfQuery, t_AMPSDBEngineResult* r_poAMPSDBEngineResult)
{
#ifdef WIN32
t_BDEngineContext* poBDEngineContext = r_pvBDEngineContext;
t_OracleContext* poOracleContext = poBDEngineContext->poDBHandle;
OCIStmt* hOCIStmt = NULL;
signed int nReturnCode = OCI_ERROR;
//allocate statement handle
nReturnCode = OCIHandleAlloc(poOracleContext->hOCIEnv, (void**)&hOCIStmt, OCI_HTYPE_STMT, 0, NULL);
if(nReturnCode == OCI_SUCCESS)
{
if(r_ulLengthOfQuery == -1)
{
r_ulLengthOfQuery = strlen(r_pcchQueryStatement);
}
nReturnCode = OCIStmtPrepare(hOCIStmt, poOracleContext->hOCIError, (unsigned char*)r_pcchQueryStatement, r_ulLengthOfQuery, OCI_NTV_SYNTAX, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
}
if(nReturnCode == OCI_SUCCESS)
{
unsigned short ushStmtType = 0;
nReturnCode = OCIAttrGet(hOCIStmt, OCI_HTYPE_STMT, &ushStmtType, NULL, OCI_ATTR_STMT_TYPE, poOracleContext->hOCIError);
if (nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
// returns 0 (ST_UNKNOWN) if sql statement is wrong
//TODO
if(OCI_STMT_SELECT == ushStmtType)
{
//Define array of define structure
//t_ColumnData poColumnDataDef[MAX_SELECT_LIST_SIZE];
OCIDefine* hOCIDefine = NULL;
OCIParam* hOCIParam = NULL;
unsigned int unSize = 0;
unsigned int unNoOfColumns = 0;
unsigned int unColumnCount = 0;
unsigned int unRowCount = 0;
memset(poOracleContext->poOracleColumnData, 0, (sizeof(t_OracleColumnData) * ORACLE_MAX_SELECT_COLUMN_LIST_SIZE));
unRowCount = (unsigned int)Oracle_GetNumberOfRecords(r_pvAMPSContext, r_pvBDEngineContext, r_pcchQueryStatement, r_ulLengthOfQuery);
if(0 == unRowCount)
{
return AMPS_ERROR_FAILURE;
}
nReturnCode = OCIStmtExecute(poOracleContext->hOCISvcCtx, hOCIStmt, poOracleContext->hOCIError, 0, 0, NULL, NULL, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
nReturnCode = OCIAttrGet(hOCIStmt, OCI_HTYPE_STMT, &unNoOfColumns, NULL, OCI_ATTR_PARAM_COUNT, poOracleContext->hOCIError);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
//get next column info
for(unColumnCount = 0; unColumnCount < unNoOfColumns; unColumnCount++)
{
nReturnCode = OCIParamGet(hOCIStmt, OCI_HTYPE_STMT, poOracleContext->hOCIError, (void**)&hOCIParam, unColumnCount + 1);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
// maximum data size in bytes
unSize = 0;
nReturnCode = OCIAttrGet(hOCIParam, OCI_DTYPE_PARAM, &unSize, NULL, OCI_ATTR_DATA_SIZE, poOracleContext->hOCIError);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
poOracleContext->poOracleColumnData[unColumnCount].puchValue = AMPS_InternalMalloc(unSize + 1);
poOracleContext->poOracleColumnData[unColumnCount].nValueLen = unSize;
memset(poOracleContext->poOracleColumnData[unColumnCount].puchValue, 0, poOracleContext->poOracleColumnData[unColumnCount].nValueLen);
nReturnCode = OCIDefineByPos(hOCIStmt, &hOCIDefine, poOracleContext->hOCIError, unColumnCount + 1, poOracleContext->poOracleColumnData[unColumnCount].puchValue, unSize, STRING_TYPE, NULL, NULL, NULL, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
return AMPS_ERROR_FAILURE;
}
}
r_poAMPSDBEngineResult->ulNumberOfColumns = unNoOfColumns;
r_poAMPSDBEngineResult->ulNumberOfRows = unRowCount;
r_poAMPSDBEngineResult->ulNumberOfResults = r_poAMPSDBEngineResult->ulNumberOfRows;
if (0 < r_poAMPSDBEngineResult->ulNumberOfRows)
{
r_poAMPSDBEngineResult->ppoAMPSDBEngineTable = (t_AMPSDBEngineTable**)AMPS_InternalMalloc(sizeof(t_AMPSDBEngineTable*) * r_poAMPSDBEngineResult->ulNumberOfRows);
if(NULL == r_poAMPSDBEngineResult->ppoAMPSDBEngineTable)
{
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for r_poBDEngineResult->ppoAMPSDBEngineTable.\n");
return AMPS_ERROR_FAILURE;
}
//printf("\n\n r_poBDEngineResult->ulNumberOfRows is %ld r_poBDEngineResult->ulNumberOfColumns %ld and r_poBDEngineResult->ppoAMPSDBEngineTable %p\n\n",r_poBDEngineResult->ulNumberOfRows, r_poBDEngineResult->ulNumberOfColumns, r_poBDEngineResult->ppoAMPSDBEngineTable);
for(unRowCount = 0; unRowCount < r_poAMPSDBEngineResult->ulNumberOfRows; unRowCount++)
{
nReturnCode = OCIStmtFetch(hOCIStmt, poOracleContext->hOCIError, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
if(nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
break;
}
r_poAMPSDBEngineResult->ppoAMPSDBEngineTable[unRowCount] = (t_AMPSDBEngineTable*)AMPS_InternalMalloc(sizeof(t_AMPSDBEngineTable) * r_poAMPSDBEngineResult->ulNumberOfColumns);
if(NULL == r_poAMPSDBEngineResult->ppoAMPSDBEngineTable[unRowCount])
{
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter].\n");
return AMPS_ERROR_FAILURE;
}
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Pointer = %p.\n", r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter]);
for(unColumnCount = 0; unColumnCount < unNoOfColumns; unColumnCount++)
{
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Column %u is %lu bytes in length and value %s.\n", (ulColumnCounter + 1), pulLengthOfField[ulColumnCounter], oMYSQLRow[ulColumnCounter]);
r_poAMPSDBEngineResult->ppoAMPSDBEngineTable[unRowCount][unColumnCount].pchField = AMPS_InternalMalloc(poOracleContext->poOracleColumnData[unColumnCount].nValueLen);
r_poAMPSDBEngineResult->ppoAMPSDBEngineTable[unRowCount][unColumnCount].nLengthOfField = poOracleContext->poOracleColumnData[unColumnCount].nValueLen;
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Field Length = %d.\n", r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter][ulColumnCounter].nLengthOfField);
memcpy(r_poAMPSDBEngineResult->ppoAMPSDBEngineTable[unRowCount][unColumnCount].pchField, poOracleContext->poOracleColumnData[unColumnCount].puchValue, poOracleContext->poOracleColumnData[unColumnCount].nValueLen);
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Filed Value = %s.\n", r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter][ulColumnCounter].pchField);
}
}
r_poAMPSDBEngineResult->ulNumberOfRows = unRowCount;
}
if(hOCIParam)
{
//ignore result code
OCIDescriptorFree(hOCIParam, OCI_DTYPE_PARAM);
}
for(unColumnCount = 0; unColumnCount < unNoOfColumns; unColumnCount++)
{
if(NULL != poOracleContext->poOracleColumnData[unColumnCount].puchValue)
{
AMPS_InternalFree(poOracleContext->poOracleColumnData[unColumnCount].puchValue);
poOracleContext->poOracleColumnData[unColumnCount].nValueLen = 0;
}
}
}
else
{
nReturnCode = OCIStmtExecute(poOracleContext->hOCISvcCtx, hOCIStmt, poOracleContext->hOCIError, 1, 0, NULL, NULL, OCI_COMMIT_ON_SUCCESS);
if (nReturnCode != OCI_SUCCESS)
{
Oracle_CheckError(r_pvAMPSContext, r_pvBDEngineContext, nReturnCode);
}
}
}
#endif
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Oracle_FreeResults
功能描述: 释放查询结果集
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvBDEngineContext 数据库应用上下文
const char* r_pcchQueryStatement SQL查询语句
unsigned long r_ulLengthOfQuery SQL查询语句长度
出参:
返回值:
int
*****************************************************************/
void Oracle_FreeResults(void* r_pvAMPSContext, void* r_pvBDEngineContext, t_AMPSDBEngineResult* r_poBDEngineResult)
{
#ifdef WIN32
unsigned long ulRowCounter = 0;
unsigned long unColumnCounter = 0;
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "No of Rows %lu.\n", r_poBDEngineResult->ulNumberOfRows);
if (0 < r_poBDEngineResult->ulNumberOfRows)
{
for(ulRowCounter = 0; ulRowCounter < r_poBDEngineResult->ulNumberOfRows; ulRowCounter++)
{
for(unColumnCounter = 0; unColumnCounter < r_poBDEngineResult->ulNumberOfColumns; unColumnCounter++)
{
AMPS_InternalFree(r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter][unColumnCounter].pchField);
r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter][unColumnCounter].nLengthOfField = 0;
}
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Free Counter %lu.\n", ulRowCounter);
//TRACE( DBE_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Pointer = %p.\n", r_poBDEngineResult)->ppoAMPSDBEngineTable[ulRowCounter]);
AMPS_InternalFree(r_poBDEngineResult->ppoAMPSDBEngineTable[ulRowCounter]);
}
r_poBDEngineResult->ulNumberOfColumns = 0;
r_poBDEngineResult->ulNumberOfRows = 0;
r_poBDEngineResult->ulNumberOfResults = 0;
AMPS_InternalFree(r_poBDEngineResult->ppoAMPSDBEngineTable);
}
//mysql_free_result(r_poBDEngineResult->pvResultObj);
#endif
}
/*****************************************************************
函数名称: Oracle_CheckError
功能描述: 错误处理函数
入参::
void* r_pvAMPSContext APMS应用上下文
void* r_pvBDEngineContext 数据库应用上下文
signed int r_nStatus 错误码
出参:
返回值:
int
*****************************************************************/
void Oracle_CheckError(void* r_pvAMPSContext, void* r_pvBDEngineContext, signed int r_nStatus)
{
#ifdef WIN32
t_BDEngineContext* poBDEngineContext = r_pvBDEngineContext;
t_OracleContext* poOracleContext = poBDEngineContext->poDBHandle;
unsigned char puchErrorBufer[512];
signed int nErrorCode = 0;
switch (r_nStatus)
{
case OCI_SUCCESS:
break;
case OCI_SUCCESS_WITH_INFO:
printf("Error - OCI_SUCCESS_WITH_INFO\n");
break;
case OCI_NEED_DATA:
printf("Error - OCI_NEED_DATA\n");
break;
case OCI_NO_DATA:
printf("Error - OCI_NODATA\n");
break;
case OCI_ERROR:
OCIErrorGet((void*)poOracleContext->hOCIError, 1, (unsigned char*) NULL, &nErrorCode, puchErrorBufer, sizeof(puchErrorBufer), OCI_HTYPE_ERROR);
printf("Error - %.*s\n", 512, puchErrorBufer);
break;
case OCI_INVALID_HANDLE:
printf("Error - OCI_INVALID_HANDLE\n");
break;
case OCI_STILL_EXECUTING:
printf("Error - OCI_STILL_EXECUTE\n");
break;
case OCI_CONTINUE:
printf("Error - OCI_CONTINUE\n");
break;
default:
break;
}
#endif
}