AMPS:Oracle数据库操作模块源码解读

  本节看看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
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值