2019-07-22 03:11:02 +00:00
|
|
|
|
#include <stdlib.h>
|
2019-07-19 07:54:36 +00:00
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <sql.h>
|
|
|
|
|
#include <sqlext.h>
|
|
|
|
|
#include <stdarg.h>
|
2019-07-19 08:02:47 +00:00
|
|
|
|
#include "database.h"
|
2019-07-19 07:54:36 +00:00
|
|
|
|
#include "cjson/cJSON.h"
|
|
|
|
|
|
2019-07-22 02:44:49 +00:00
|
|
|
|
/* 保存列信息的数据结构 */
|
2019-07-19 07:54:36 +00:00
|
|
|
|
typedef struct column_info
|
|
|
|
|
{
|
|
|
|
|
char name[30];
|
|
|
|
|
SQLSMALLINT nameLength;
|
|
|
|
|
|
|
|
|
|
SQLSMALLINT dateType;
|
|
|
|
|
SQLULEN columnSize;
|
|
|
|
|
SQLSMALLINT decimalDigits;
|
|
|
|
|
SQLSMALLINT nullable;
|
|
|
|
|
}COLUMN_INFO_T;
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 打印异常信息
|
|
|
|
|
* Input:
|
|
|
|
|
* hEnv - 环境变量
|
|
|
|
|
* hDbc - 连接句柄
|
|
|
|
|
* hStmt - 新分配的数据结构的句柄缓冲区的指针
|
|
|
|
|
* Output:
|
|
|
|
|
* 无
|
|
|
|
|
* Return:
|
|
|
|
|
* 无
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
static void DumpODBCLog(SQLHENV hEnv, SQLHDBC hDbc, SQLHSTMT hStmt)
|
|
|
|
|
{
|
|
|
|
|
SQLTCHAR szError[501];
|
|
|
|
|
SQLTCHAR szSqlState[10];
|
|
|
|
|
SQLINTEGER nNativeError;
|
|
|
|
|
SQLSMALLINT nErrorMsg;
|
|
|
|
|
|
|
|
|
|
if (hStmt != NULL)
|
|
|
|
|
{
|
|
|
|
|
while ( SQLError( hEnv, hDbc, hStmt, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS )
|
|
|
|
|
{
|
|
|
|
|
printf( "%s\n", szError);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hDbc != NULL)
|
|
|
|
|
{
|
|
|
|
|
while ( SQLError( hEnv, hDbc, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS )
|
|
|
|
|
{
|
|
|
|
|
printf( "%s\n", szError);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hEnv != NULL)
|
|
|
|
|
{
|
|
|
|
|
while ( SQLError( hEnv, 0, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS )
|
|
|
|
|
{
|
|
|
|
|
printf( "%s\n", szError);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 连接数据库操作
|
|
|
|
|
* Input:
|
|
|
|
|
* module_id - 模块ID,每个模块需要向数据库模块设置模块ID,用于打印、统计使用
|
|
|
|
|
* Output:
|
|
|
|
|
* 无
|
|
|
|
|
* Return:
|
|
|
|
|
* 数据库句柄
|
|
|
|
|
* NULL - 连接数据库失败
|
|
|
|
|
* 非NULL - 连接数据库成功
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
void * connect_database (int module_id)
|
|
|
|
|
{
|
|
|
|
|
SQLHENV henv = NULL;
|
|
|
|
|
SQLHDBC hdbc = NULL;
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
|
|
|
|
|
SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
|
|
|
|
SQLSetEnvAttr( henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0 );
|
|
|
|
|
SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc );
|
|
|
|
|
|
|
|
|
|
SQLSetConnectAttr( hdbc, SQL_ATTR_ODBC_CURSORS, (SQLPOINTER)SQL_CUR_USE_ODBC, 0 );
|
|
|
|
|
ret = SQLConnect( hdbc, "meng", SQL_NTS, "", SQL_NTS, "", SQL_NTS );
|
|
|
|
|
|
|
|
|
|
DumpODBCLog(NULL, hdbc, NULL);
|
|
|
|
|
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return hdbc;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 释放数据库连接
|
|
|
|
|
* Input:
|
|
|
|
|
* module_id - 模块ID,每个模块需要向数据库模块设置模块ID,用于打印、统计使用
|
|
|
|
|
* db_handle - 数据库句柄
|
|
|
|
|
* Output:
|
|
|
|
|
* 无
|
|
|
|
|
* Return:
|
|
|
|
|
* DB_RET_PARAM_NULL - 入参指针为NULL
|
|
|
|
|
* DB_RET_ERR - 释放失败
|
|
|
|
|
* DB_RET_OK - 释放成功
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
int disconnect_database (int module_id, void * db_handle)
|
|
|
|
|
{
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
if (NULL == db_handle)
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_PARAM_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLDisconnect(db_handle);
|
|
|
|
|
ret = SQLFreeHandle(SQL_HANDLE_DBC, db_handle);
|
|
|
|
|
if (ret != SQL_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DB_RET_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 创建数据库表
|
|
|
|
|
* Input:
|
|
|
|
|
* module_id - 模块ID,每个模块需要向数据库模块设置模块ID,用于打印、统计使用
|
|
|
|
|
* db_handle - 数据库句柄
|
|
|
|
|
* table_name - 创建的表名
|
|
|
|
|
* sql_str - 创建表的SQL语句
|
|
|
|
|
* Output:
|
|
|
|
|
* 无
|
|
|
|
|
* Return:
|
|
|
|
|
* DB_RET_PARAM_NULL - 入参指针为NULL
|
|
|
|
|
* DB_RET_ERR - 释放失败
|
|
|
|
|
* DB_RET_OK - 释放成功
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
int create_database_table(int module_id, void * db_handle, char * table_name, char * sql_str)
|
|
|
|
|
{
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
SQLHSTMT hstmt;
|
|
|
|
|
|
|
|
|
|
if ((NULL == db_handle) || (NULL == table_name) || (NULL == sql_str))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_PARAM_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = SQLAllocHandle( SQL_HANDLE_STMT, db_handle, &hstmt);
|
|
|
|
|
if ((SQL_INVALID_HANDLE == ret) || (SQL_ERROR == ret))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = SQLExecDirect(hstmt, sql_str, SQL_NTS);
|
|
|
|
|
|
|
|
|
|
SQLCloseCursor(hstmt);
|
|
|
|
|
SQLFreeStmt(hstmt, SQL_DROP);
|
|
|
|
|
|
|
|
|
|
if (ret != SQL_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DB_RET_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 对据库表执行插入、删除、更新操作
|
|
|
|
|
* Input:
|
|
|
|
|
* module_id - 模块ID,每个模块需要向数据库模块设置模块ID,用于打印、统计使用
|
|
|
|
|
* db_handle - 数据库句柄
|
|
|
|
|
* op_type - 操作类型 DB_OP_INSERT:插入数据 DB_OP_DEL:删除数据 DB_OP_UPDATE:更新数据
|
|
|
|
|
* table_name - 创建的表名
|
|
|
|
|
* sql_str - 创建表的SQL语句
|
|
|
|
|
* param_num - 扩展参数组合数量,填写0表示没有,需要防止SQL注入问题,需要使用扩展参数组合
|
|
|
|
|
* Output:
|
|
|
|
|
* 无
|
|
|
|
|
* Return:
|
|
|
|
|
* DB_RET_PARAM_NULL - 入参指针为NULL
|
2019-07-22 02:44:49 +00:00
|
|
|
|
* DB_RET_PARAM_ERR - 入参错误
|
2019-07-19 07:54:36 +00:00
|
|
|
|
* DB_RET_ERR - 操作失败
|
|
|
|
|
* DB_RET_OK - 操作成功
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
int update_database(int module_id, void * db_handle, int op_type, char * table_name, char * sql_str, int param_num, ...)
|
|
|
|
|
{
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
SQLHSTMT hstmt;
|
|
|
|
|
SQLUSMALLINT RowStatusArray[DB_ROWS];
|
|
|
|
|
|
|
|
|
|
if ((NULL == db_handle) || (NULL == table_name) || (NULL == sql_str))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_PARAM_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((op_type != DB_OP_INSERT) && (op_type != DB_OP_DEL) && (op_type != DB_OP_UPDATE))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_PARAM_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLAllocHandle(SQL_HANDLE_STMT, db_handle, &hstmt);
|
|
|
|
|
if ((SQL_INVALID_HANDLE == ret) || (SQL_ERROR == ret))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_VALUES, 0);
|
|
|
|
|
SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_STATIC, 0);
|
|
|
|
|
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)DB_COLUMN, 20 );
|
|
|
|
|
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);
|
|
|
|
|
SQLSetCursorName(hstmt, "ORDERCURSOR", SQL_NTS );
|
|
|
|
|
|
|
|
|
|
/* 是否存在扩展参数,会采用不同的处理流程 */
|
|
|
|
|
if (0 == param_num)
|
|
|
|
|
{
|
|
|
|
|
ret = SQLExecDirect(hstmt, sql_str, SQL_NTS);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
int type;
|
|
|
|
|
int len;
|
|
|
|
|
SQLLEN ind_name = SQL_NTS;
|
|
|
|
|
long long int_temp;
|
|
|
|
|
va_list ap;
|
|
|
|
|
double double_temp;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQLPrepare(hstmt, sql_str, SQL_NTS);
|
|
|
|
|
va_start(ap, param_num);
|
|
|
|
|
|
|
|
|
|
/* 执行参数绑定操作 */
|
|
|
|
|
for (i = 1; i <= param_num; i++)
|
|
|
|
|
{
|
|
|
|
|
type = va_arg(ap, int);
|
|
|
|
|
len = va_arg(ap, int);
|
|
|
|
|
|
|
|
|
|
if (DB_DATA_INT_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
int_temp = va_arg(ap, long long);
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_C_UBIGINT, len, 0, &int_temp, len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else if (DB_DATA_STRING_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR , len, 0, va_arg(ap, char *), len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else if (DB_DATA_FLOAT_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
double_temp = va_arg(ap, double);
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, len, 0, &double_temp, len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("\n type error : %d", type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
|
|
ret = SQLExecute(hstmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLCloseCursor(hstmt);
|
|
|
|
|
SQLFreeStmt(hstmt, SQL_DROP);
|
|
|
|
|
|
|
|
|
|
if (ret != SQL_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
DumpODBCLog(NULL, db_handle, hstmt);
|
|
|
|
|
return DB_RET_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DB_RET_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 根据指定信息查找数据库
|
|
|
|
|
* Input:
|
|
|
|
|
* module_id - 模块ID,每个模块需要向数据库模块设置模块ID,用于打印、统计使用
|
|
|
|
|
* db_handle - 数据库句柄
|
|
|
|
|
* table_name - 创建的表名
|
|
|
|
|
* sql_str - 创建表的SQL语句
|
|
|
|
|
* begin_num - 从第几条查询结果开始返回
|
|
|
|
|
* need_num - 应用需要返回的结果条数
|
|
|
|
|
* param_num - 扩展参数组合数量,填写0表示没有,需要防止SQL注入问题,需要使用扩展参数组合
|
|
|
|
|
* Output:
|
|
|
|
|
* return_num - 实际返回的结果条数
|
|
|
|
|
* Return:
|
|
|
|
|
* NULL - 操作失败
|
|
|
|
|
* 非NULL - 返回CJSON格式的查询结果
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
void * select_datebase_by_number(int module_id, void * db_handle, char * table_name, char * sql_str, int begin_num, int need_num, int * return_num, int param_num, ...)
|
|
|
|
|
{
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
SQLHSTMT hstmt;
|
|
|
|
|
SQLUSMALLINT RowStatusArray[DB_ROWS];
|
|
|
|
|
SQLSMALLINT nameLength = 0;
|
|
|
|
|
SQLSMALLINT dateType = 0;
|
|
|
|
|
SQLULEN columnSize = 0;
|
|
|
|
|
SQLSMALLINT decimalDigits = 0;
|
|
|
|
|
SQLSMALLINT nullable = 0;
|
|
|
|
|
SQLRETURN retcode = 0;
|
|
|
|
|
int i = 0;
|
|
|
|
|
int j = 0;
|
|
|
|
|
COLUMN_INFO_T db_column_info[20];
|
|
|
|
|
int column_nmuber = 0;
|
|
|
|
|
SQLCHAR value[DB_ROWS][DB_COLUMN][DB_ROWS_MAX_LEN];
|
|
|
|
|
int ret_num = 0;
|
|
|
|
|
SQLUINTEGER FetchOrientation;
|
|
|
|
|
SQLLEN cbValue[DB_ROWS][DB_ROWS_MAX_LEN];
|
2019-07-22 02:44:49 +00:00
|
|
|
|
cJSON *json = NULL;
|
2019-07-19 07:54:36 +00:00
|
|
|
|
char *json_data = NULL;
|
|
|
|
|
cJSON *array = NULL;
|
|
|
|
|
cJSON * obj = NULL;
|
|
|
|
|
|
|
|
|
|
if ((NULL == db_handle) || (NULL == table_name) || (NULL == sql_str))
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((begin_num <= 0) || (need_num <= 0))
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = SQLAllocHandle( SQL_HANDLE_STMT, db_handle, &hstmt);
|
|
|
|
|
if ((SQL_INVALID_HANDLE == ret) || (SQL_ERROR == ret))
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_VALUES, 0 );
|
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_STATIC, 0 );
|
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)DB_COLUMN, 20 );
|
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0 );
|
|
|
|
|
SQLSetCursorName( hstmt, "ORDERCURSOR", SQL_NTS );
|
|
|
|
|
|
|
|
|
|
SQLPrepare( hstmt, sql_str, SQL_NTS );
|
|
|
|
|
|
|
|
|
|
column_nmuber = 1;
|
|
|
|
|
|
|
|
|
|
/* 解析查询结果中包含的列信息 */
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
retcode = SQLDescribeCol(hstmt, column_nmuber, db_column_info[column_nmuber].name, sizeof(db_column_info[column_nmuber].name), &db_column_info[column_nmuber].nameLength,
|
|
|
|
|
&db_column_info[column_nmuber].dateType, &db_column_info[column_nmuber].columnSize,
|
|
|
|
|
&db_column_info[column_nmuber].decimalDigits, &db_column_info[column_nmuber].nullable);
|
|
|
|
|
if (retcode != SQL_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
column_nmuber--;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
column_nmuber++;
|
|
|
|
|
}while(1);
|
|
|
|
|
|
|
|
|
|
/* 如果列为0,返回查询结果 */
|
|
|
|
|
if (0 == column_nmuber)
|
|
|
|
|
{
|
|
|
|
|
SQLCloseCursor(hstmt);
|
|
|
|
|
SQLFreeStmt(hstmt, SQL_DROP);
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-22 10:08:26 +00:00
|
|
|
|
*return_num = 0;
|
|
|
|
|
|
2019-07-19 07:54:36 +00:00
|
|
|
|
/* 是否存在扩展参数,会采用不同的处理流程 */
|
|
|
|
|
if (0 == param_num)
|
|
|
|
|
{
|
|
|
|
|
ret = SQLExecDirect(hstmt, sql_str, SQL_NTS);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
int type;
|
|
|
|
|
int len;
|
|
|
|
|
SQLLEN ind_name = SQL_NTS;
|
|
|
|
|
long long int_temp;
|
|
|
|
|
va_list ap;
|
|
|
|
|
double double_temp;
|
|
|
|
|
|
|
|
|
|
SQLPrepare(hstmt, sql_str, SQL_NTS);
|
|
|
|
|
|
|
|
|
|
va_start(ap, param_num);
|
|
|
|
|
|
|
|
|
|
for (i = 1; i <= param_num; i++)
|
|
|
|
|
{
|
|
|
|
|
type = va_arg(ap, int);
|
|
|
|
|
len = va_arg(ap, int);
|
|
|
|
|
|
|
|
|
|
if (DB_DATA_INT_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
int_temp = va_arg(ap, long long);
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_C_UBIGINT, len, 0, &int_temp, len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else if (DB_DATA_STRING_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR , len, 0, va_arg(ap, char*), len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else if (DB_DATA_FLOAT_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
double_temp = va_arg(ap, double);
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, len, 0, &double_temp, len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
|
|
ret = SQLExecute(hstmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ret != SQL_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
SQLCloseCursor(hstmt);
|
|
|
|
|
SQLFreeStmt(hstmt, SQL_DROP);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-22 02:44:49 +00:00
|
|
|
|
json = cJSON_CreateObject();
|
|
|
|
|
|
2019-07-19 07:54:36 +00:00
|
|
|
|
/* 将应用程序数据缓冲区绑定到结果集中的列 */
|
|
|
|
|
for (i = 1; i <= column_nmuber; i++)
|
|
|
|
|
{
|
|
|
|
|
if (SQL_BIGINT == db_column_info[i].dateType)
|
|
|
|
|
{
|
|
|
|
|
SQLBindCol(hstmt, i, SQL_C_UBIGINT, value[i][0], DB_ROWS_MAX_LEN, cbValue[i]);
|
|
|
|
|
}
|
|
|
|
|
else if (SQL_CHAR == db_column_info[i].dateType)
|
|
|
|
|
{
|
|
|
|
|
SQLBindCol(hstmt, i, db_column_info[i].dateType, value[i][0], DB_ROWS_MAX_LEN, cbValue[i]);
|
|
|
|
|
}
|
|
|
|
|
else if (SQL_DOUBLE == db_column_info[i].dateType)
|
|
|
|
|
{
|
|
|
|
|
SQLBindCol(hstmt, i, db_column_info[i].dateType, value[i][0], 0, cbValue[i]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cJSON_AddItemToObject(json, "data", array = cJSON_CreateArray());
|
|
|
|
|
|
|
|
|
|
/* 查询结果 */
|
|
|
|
|
FetchOrientation = SQL_FETCH_RELATIVE;
|
|
|
|
|
for (i = 1; i <= need_num; i++)
|
|
|
|
|
{
|
|
|
|
|
ret = SQLFetchScroll(hstmt, FetchOrientation, begin_num);
|
|
|
|
|
FetchOrientation = SQL_FETCH_NEXT;
|
|
|
|
|
if (ret != SQL_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret_num++;
|
|
|
|
|
|
|
|
|
|
cJSON_AddItemToArray(array, obj = cJSON_CreateObject());
|
|
|
|
|
|
|
|
|
|
for (j = 1; j <= column_nmuber; j++)
|
|
|
|
|
{
|
|
|
|
|
printf("\n db_column_info[j].dateType: %d j : %d", db_column_info[j].dateType, j);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (SQL_BIGINT == db_column_info[j].dateType)
|
|
|
|
|
{
|
|
|
|
|
cJSON_AddNumberToObject(obj, db_column_info[j].name, *((long long *)&(value[j][0])));
|
|
|
|
|
}
|
|
|
|
|
else if (SQL_CHAR == db_column_info[j].dateType)
|
|
|
|
|
{
|
|
|
|
|
cJSON_AddStringToObject(obj, db_column_info[j].name , value[j][0]);
|
|
|
|
|
}
|
|
|
|
|
else if (SQL_DOUBLE == db_column_info[j].dateType)
|
|
|
|
|
{
|
|
|
|
|
cJSON_AddNumberToObject(obj, db_column_info[j].name , *((double *)&(value[j][0])));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLCloseCursor(hstmt);
|
|
|
|
|
SQLFreeStmt(hstmt, SQL_DROP);
|
|
|
|
|
|
|
|
|
|
*return_num = ret_num;
|
|
|
|
|
|
|
|
|
|
if (ret_num != 0)
|
|
|
|
|
{
|
|
|
|
|
json_data = cJSON_Print(json);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-22 02:44:49 +00:00
|
|
|
|
cJSON_Delete(json);
|
|
|
|
|
|
2019-07-19 07:54:36 +00:00
|
|
|
|
return json_data;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-22 02:44:49 +00:00
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 释放查询接口申请的内存
|
|
|
|
|
* Input:
|
|
|
|
|
* module_id - 模块ID,每个模块需要向数据库模块设置模块ID,用于打印、统计使用
|
|
|
|
|
* table_name - 创建的表名
|
|
|
|
|
* memory_ptr - 待释放内存指针
|
|
|
|
|
* Output:
|
|
|
|
|
* 无
|
|
|
|
|
* Return:
|
|
|
|
|
* DB_RET_PARAM_NULL - 入参指针为NULL
|
|
|
|
|
* DB_RET_ERR - 操作失败
|
|
|
|
|
* DB_RET_OK - 操作成功
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
int free_database_memory(int module_id, char * table_name, void * memory_ptr)
|
|
|
|
|
{
|
|
|
|
|
if ((NULL == table_name) && (NULL == memory_ptr))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_PARAM_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(memory_ptr);
|
|
|
|
|
|
|
|
|
|
return DB_RET_OK;
|
|
|
|
|
}
|
2019-07-19 07:54:36 +00:00
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Description:
|
|
|
|
|
* 返回根据指定信息查找数据库的结果的条目数
|
|
|
|
|
* Input:
|
|
|
|
|
* module_id - 模块ID,每个模块需要向数据库模块设置模块ID,用于打印、统计使用
|
|
|
|
|
* db_handle - 数据库句柄
|
|
|
|
|
* table_name - 创建的表名
|
|
|
|
|
* sql_str - 创建表的SQL语句
|
|
|
|
|
* param_num - 扩展参数组合数量,填写0表示没有,需要防止SQL注入问题,需要使用扩展参数组合
|
|
|
|
|
* Output:
|
|
|
|
|
* ret_num - 实际返回的结果条数
|
|
|
|
|
* Return:
|
|
|
|
|
* DB_RET_PARAM_NULL - 入参指针为NULL
|
|
|
|
|
* DB_RET_ERR - 操作失败
|
|
|
|
|
* DB_RET_OK - 操作成功
|
|
|
|
|
* Others:
|
|
|
|
|
* 无
|
|
|
|
|
**********************************************************************************/
|
|
|
|
|
int get_select_datebase_number(int module_id, void * db_handle, char * table_name, char * sql_str, int * ret_num, int param_num, ...)
|
|
|
|
|
{
|
|
|
|
|
SQLRETURN ret;
|
|
|
|
|
SQLHSTMT hstmt;
|
|
|
|
|
SQLUSMALLINT RowStatusArray[DB_ROWS];
|
|
|
|
|
SQLSMALLINT nameLength = 0;
|
|
|
|
|
SQLSMALLINT dateType = 0;
|
|
|
|
|
SQLULEN columnSize = 0;
|
|
|
|
|
SQLSMALLINT decimalDigits = 0;
|
|
|
|
|
SQLSMALLINT nullable = 0;
|
|
|
|
|
SQLRETURN retcode = 0;
|
|
|
|
|
int i = 0;
|
|
|
|
|
int j = 0;
|
|
|
|
|
COLUMN_INFO_T db_column_info[20];
|
|
|
|
|
int column_nmuber = 0;
|
|
|
|
|
SQLCHAR value[DB_ROWS][DB_COLUMN][DB_ROWS_MAX_LEN];
|
|
|
|
|
int returnNum = 0;
|
|
|
|
|
SQLUINTEGER FetchOrientation;
|
|
|
|
|
SQLLEN cbValue[DB_ROWS_MAX_LEN][DB_ROWS];
|
|
|
|
|
SQLLEN count;
|
|
|
|
|
|
|
|
|
|
if ((NULL == db_handle) || (NULL == table_name) || (NULL == sql_str))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_PARAM_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = SQLAllocHandle( SQL_HANDLE_STMT, db_handle, &hstmt);
|
|
|
|
|
if ((SQL_INVALID_HANDLE == ret) || (SQL_ERROR == ret))
|
|
|
|
|
{
|
|
|
|
|
return DB_RET_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-22 10:08:26 +00:00
|
|
|
|
*ret_num = 0;
|
|
|
|
|
|
2019-07-19 07:54:36 +00:00
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_VALUES, 0 );
|
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_STATIC, 0 );
|
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)DB_COLUMN, 20 );
|
|
|
|
|
SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0 );
|
|
|
|
|
SQLSetCursorName( hstmt, "ORDERCURSOR", SQL_NTS );
|
|
|
|
|
|
|
|
|
|
SQLPrepare( hstmt, sql_str, SQL_NTS );
|
|
|
|
|
|
|
|
|
|
if (0 == param_num)
|
|
|
|
|
{
|
|
|
|
|
ret = SQLExecDirect(hstmt, sql_str, SQL_NTS);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
int type;
|
|
|
|
|
int len;
|
|
|
|
|
SQLLEN ind_name = SQL_NTS;
|
|
|
|
|
long long int_temp;
|
|
|
|
|
va_list ap;
|
|
|
|
|
double double_temp;
|
|
|
|
|
|
|
|
|
|
SQLPrepare(hstmt, sql_str, SQL_NTS);
|
|
|
|
|
|
|
|
|
|
va_start(ap, param_num);
|
|
|
|
|
|
|
|
|
|
for (i = 1; i <= param_num; i++)
|
|
|
|
|
{
|
|
|
|
|
type = va_arg(ap, int);
|
|
|
|
|
len = va_arg(ap, int);
|
|
|
|
|
|
|
|
|
|
if (DB_DATA_INT_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
int_temp = va_arg(ap, long long);
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_C_UBIGINT, len, 0, &int_temp, len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else if (DB_DATA_STRING_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR , len, 0, va_arg(ap, char*), len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else if (DB_DATA_FLOAT_TYPE == type)
|
|
|
|
|
{
|
|
|
|
|
double_temp = va_arg(ap, double);
|
|
|
|
|
ret = SQLBindParameter(hstmt, i, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, len, 0, &double_temp, len, &ind_name);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = SQLExecute(hstmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ret != SQL_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
SQLCloseCursor(hstmt);
|
|
|
|
|
SQLFreeStmt(hstmt, SQL_DROP);
|
|
|
|
|
return DB_RET_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLRowCount( hstmt, &count);
|
|
|
|
|
|
|
|
|
|
*ret_num = count;
|
|
|
|
|
|
|
|
|
|
SQLCloseCursor(hstmt);
|
|
|
|
|
SQLFreeStmt(hstmt, SQL_DROP);
|
|
|
|
|
|
|
|
|
|
return DB_RET_OK;
|
|
|
|
|
}
|