⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 db_op.ec

📁 界面库
💻 EC
📖 第 1 页 / 共 5 页
字号:
/*========================================================================
功能: 		对数据库表操作	
作者:
王永忠:	2001/03/31:规范程序设计
王永忠:	2001/04/02:修改原merchant为merchant_base
	增加根据商户号到商户受理卡类资料表中查找该商户的受理卡
	类信息,并设置卡使能状态数组。
王永忠:	2001/04/09:修改路由表操作函数
周国祥:2001/04/27: 放开load_mcc_param()函数
王永忠:	2001/07/09:修改update_table()函数,增加返回码1
王永忠:	2001/08/21:将AUTH_PUR(授权消费)从卡段交易路由中移到交易
	路由中.
王永忠:	2001/09/26:在load_bank_tab()中添加对$(WORKDIR)/etc/IP_FILTER
	文件的处理, 以便在网间处理时不再查询数据库系统, 并且不需要
	人工维护该文件.
王永忠:	2001/10/16:添加select_tran_ls()函数用来在有些地方替换用来使用的
	select_ls_record()函数。
王永忠:	2001/10/19:在select_tran_ls()函数添加对OFFLINE交易的支持

周国祥:	2002/05/10:增加load_bank_tab_netm()函数, 添加对网控器监控的支持

=========================================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include "mytools.h"
#include "shmsys.h"
#include "macro_def.h"
#include "public.h"
$include "db_struct.h"
$include sqlca;
	
extern	int	errno;

void error_handler ();
void warning_handler ();
void notfound_handler ();

EXEC SQL WHENEVER SQLERROR CALL error_handler;
EXEC SQL WHENEVER SQLWARNING CALL warning_handler;
EXEC SQL WHENEVER NOT FOUND CALL notfound_handler;

EXEC SQL BEGIN DECLARE SECTION;
S_sys_param		G_sys_param;
S_merchant_base		G_merchant_base;
S_merchant_switch	G_merchant_switch;
S_edc_terminal		G_edc_terminal;
S_edc_card		G_edc_card;
S_bank_base		G_bank_base;

S_wb_list		G_wb_list;

S_saf_ls		G_saf_ls;
S_tran_ls		G_tran_ls;

S_sys_module		G_sys_module;

S_mcc_param		*G_mcc_par=NULL;

short			indi;
int 			G_bank_base_num;
int 			G_card_router_num;
int 			G_tran_router_num;
int 			G_bankcard_router_num;
int 			G_adv_router_num;

int 			G_mcc_table_size;

S_default_route		G_default_router;
S_card_route  		*G_card_router_tab=NULL;
S_tran_route  		*G_tran_router_tab=NULL;
S_bankcard_route  	*G_bankcard_router_tab=NULL;
S_adv_route		*G_adv_router_tab=NULL;

S_bank_base 		*G_bank_tab=NULL;

S_tran_limit_amt	G_tran_limit_amt;

EXEC SQL END DECLARE SECTION;

int bank_cmp ( void *bank1 , void *bank2 );


/***************************************************************
功能:
	从cur_tran_ls表中获得交易统计
ENTRY:	
	sqlstring 此串中必须使用 select count(*), sum(amount) from 
RETURN:	-1,	FAIL
	0,	SUCC, RESULT-->num, amt 
****************************************************************/
int select_posls_total( sqlstring, num, amt )
char		*sqlstring;
int		*num;
double		*amt;
{

EXEC SQL BEGIN DECLARE SECTION;
char		sqlstr[1024];
int		num0;
double		amt0;
EXEC SQL END DECLARE SECTION;


	if (strlen(sqlstring) > 1024)
		return -1;
	else
		strcpy( sqlstr, sqlstring );

	num0 = 0;
	amt0 = 0;

	EXEC SQL PREPARE sel_posls_t FROM :sqlstr;
	EXEC SQL DECLARE sel_ls CURSOR WITH HOLD FOR sel_posls_t;
	if( SQLCODE<0 ) {
		errcall(ERROR, "DECLARE数据库游标失败[%ld][%s]", SQLCODE, sqlstr);
		return -1;
	}

	EXEC SQL OPEN sel_ls;
	if( SQLCODE<0 ) {
		errcall(ERROR, "OPEN数据库游标失败[%ld][%s]", SQLCODE, sqlstr);
		return -1;
	}

	EXEC SQL FETCH sel_ls INTO :num0, :amt0:indi;
	if( SQLCODE<0 ) {
		errcall(ERROR, "FETCH数据库游标失败[%ld][%s]", SQLCODE, sqlstr);
		EXEC SQL CLOSE sel_ls;
		return -1;
	}
	EXEC SQL CLOSE sel_ls;
	
	if(num0 == 0)
		amt0 = 0;
	*num = num0;
	*amt = amt0;

	return 0;
}


/***************************************************************
功能:
	用于查询 cur_tran_ls, his_tran_ls, err_tran_ls 表中
	唯一记录 --> po

ENTRY:		sqlstr	格式必须为: select * from 
		po	用来保存找到的原交易信息
		pb	PUBLIC结构
RETURN:		-1	FAIL
		0	FOUND
		-2	NOT FOUND
****************************************************************/
int select_tran_ls( sqlstring, po, pb)
char			*sqlstring;
S_tran_ls		*po;
PUBLIC			*pb;
{

EXEC SQL BEGIN DECLARE SECTION;
char		sqlstr[1024];
S_tran_ls	posls;
EXEC SQL END DECLARE SECTION;

	if (strlen(sqlstring) > 1024)
	{
		errcall(ERROR, "SQL语句长度超过系统设置的字节数,SQL[%s]", sqlstring);
		return -1;
	}
	else
		strcpy( sqlstr, sqlstring );

	//现在查找原交易的原则为根据一定的条件,将可能满足的记录取出,
	//然后在这些记录中查找,这种方法可以使用数据库系统的索引,从而
	//提高查找原交易的速度

	EXEC SQL PREPARE sel_tran_ls FROM :sqlstr;
	EXEC SQL DECLARE sel_tran_ls_cur CURSOR WITH HOLD FOR sel_tran_ls;
	if( SQLCODE < 0 ) {
		errcall(ERROR, "DECLARE数据库游标失败[%ld] [%s]", SQLCODE, sqlstr);
		return -1;
	}

	EXEC SQL OPEN sel_tran_ls_cur;
	if( SQLCODE < 0 ) {
		errcall(ERROR, "OPEN数据库游标失败[%ld] [%s]", SQLCODE, sqlstr);
		return -1;
	}

	while(1) {
		//循环查找流水记录
		EXEC SQL FETCH sel_tran_ls_cur INTO 	:posls; 
		if( SQLCODE < 0 ) {
			errcall(ERROR, "Fetch数据库游标失败[%ld][%s]", SQLCODE, sqlstr);
			EXEC SQL CLOSE sel_tran_ls_cur;
			return -1;
		}
	
		if( SQLCODE == SQLNOTFOUND ) {
			errcall(DEBUG, "没有找到交易的原交易信息!!");
			EXEC SQL CLOSE sel_tran_ls_cur;
			return -2;
		}

		del_st_space("cur_tran_ls", &posls);

		//根据交易类型进行不同的原交易判断
		switch(pb->Tran_type) {
		case	POS_VOID:
		
		if(pb->Void_invoice_no != 0) {
			//增加撤消交易金额为0时, 查找原交易时不使用交易金额
			//作为判断条件
			if (fabs(atol(pb->Tran_amount)/100.) < 0.01){
				if (posls.tran_flag[0]	== '0'		&&
			    	posls.saf_flag[0]	== '0'		&&
			    	posls.snd_settle_flag[0]== 'N'		&&
			    	posls.invoice_no	== pb->Void_invoice_no	&&
#if 0
			    	posls.tran_type		== pb->Void_tran_type	&&
#endif
			    	!strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
				}
				else
					break;
			}
			else {//(pb->Tran_amount != 0)
				if (posls.tran_flag[0]	== '0'		&&
			    	posls.saf_flag[0]	== '0'		&&
			    	posls.snd_settle_flag[0]== 'N'		&&
			    	posls.invoice_no	== pb->Void_invoice_no	&&
#if 0
			    	posls.tran_type		== pb->Void_tran_type	&&
#endif
			    	fabs(atol(pb->Tran_amount)/100. - posls.tran_amt) < 0.01	&&
			    	!strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
				}
				else
					break;
			}
		 }
		 else {//(pb->Void_invoice_no == 0)
		//修改票据号为0时, 原使用TRACE_NO作为查找原交易的依据, 
		//为使用AUTH_NO作为查找原交易的依据.
			if (fabs(atol(pb->Tran_amount)/100.) < 0.01){
				if (posls.tran_flag[0]	== '0'		&&
			    	posls.saf_flag[0]	== '0'		&&
			    	posls.snd_settle_flag[0]== 'N'		&&
#if 0
			    	posls.tran_type		== pb->Void_tran_type	&&
#endif
			    	!strcmp(posls.auth_no, pb->Auth_no)	&&
			    	!strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
				}
				else
					break;
			}
			else {//(pb->Tran_amount != 0)
				if (posls.tran_flag[0]	== '0'		&&
			    	posls.saf_flag[0]	== '0'		&&
			    	posls.snd_settle_flag[0]== 'N'		&&
#if 0
			    	posls.tran_type		== pb->Void_tran_type	&&
#endif
			    	fabs(atol(pb->Tran_amount)/100. - posls.tran_amt) < 0.01	&&
			    	!strcmp(posls.auth_no, pb->Auth_no)			&&
			    	!strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
				}
				else
					break;
			}
		} 

		case	REVERSAL:
$ifdef zgx021122_modi;
		if (pb->Invoice_no != 0) {
$else;
		if (pb->Void_invoice_no != 0) {
$endif;
			if (posls.saf_flag[0]	== '0'		&&
			    posls.tran_flag[0]	== '0'		&&
$ifdef zgx021122_modi;
			    posls.invoice_no	== pb->Invoice_no	&&
$else;
			    posls.invoice_no	== pb->Invoice_no	&&
			    posls.void_invoice_no	== pb->Void_invoice_no	&&
$endif;
			    posls.snd_settle_flag[0]== 'N'		&&
			    posls.rcv_settle_flag[0]== 'N'		&&
			    posls.agt_settle_flag[0]== 'N'		&&
			    posls.adv_settle_flag[0]== 'N'		&&
#if 0
			    (fabs(posls.tran_amt - atol(pb->Tran_amount)/100.) < 0.001)	&&
#endif
			    !strcmp(posls.resp_code, SUCCESS)){
				EXEC SQL CLOSE sel_tran_ls_cur;
				memcpy( po, &posls, sizeof( S_tran_ls ) );
				return 0;
			}
			else
				break;
		}
		else {
			if (posls.saf_flag[0]	== '0'		&&
			    posls.tran_flag[0]	== '0'		&&
			    posls.snd_settle_flag[0]== 'N'		&&
			    posls.rcv_settle_flag[0]== 'N'		&&
			    posls.agt_settle_flag[0]== 'N'		&&
			    posls.adv_settle_flag[0]== 'N'		&&
#if 0
			    (fabs(posls.tran_amt - atol(pb->Tran_amount)/100.) < 0.001)	&&
#endif
			    !strcmp(posls.auth_no, pb->Auth_no)		&&
			    !strcmp(posls.resp_code, SUCCESS)){
				EXEC SQL CLOSE sel_tran_ls_cur;
				memcpy( po, &posls, sizeof( S_tran_ls ) );
				return 0;
			}
			else
				break;
		}

		case	CONFIRM:
		
			if (posls.tran_flag[0]	== '0'		&&
			    posls.saf_flag[0]	== '0'		&&
			    posls.tran_type	== PRE_AUTH	&&
			    !strcmp(posls.auth_no, pb->Auth_no)	&&
			    !strcmp(posls.resp_code, SUCCESS)){
				EXEC SQL CLOSE sel_tran_ls_cur;
				memcpy( po, &posls, sizeof( S_tran_ls ) );
				return 0;
			}
			else
				break;


		case	REFUND:
		case	ADJUST:
		
		    if(pb->Void_invoice_no != 0) {
			if (posls.tran_flag[0]	== '0'		&&
			    	posls.saf_flag[0]	== '0'		&&
			    	posls.invoice_no	== pb->Void_invoice_no	&&
			    	(posls.tran_type	== CONFIRM	||
			    	 posls.tran_type	== PURCHASE)	&&
			    	!strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
			}
			else
				break;
		    } 
		    else {
			if (posls.tran_flag[0]	== '0'		&&
			    	posls.saf_flag[0]	== '0'		&&
			    	posls.trace_no		== pb->Void_trace_no	&&
			    	(posls.tran_type	== CONFIRM	||
			    	 posls.tran_type	== PURCHASE)	&&
			    	!strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
			}
			else
				break;
		    }


#ifdef wyz_add_010705
		case PRE_AUTH:
			if (posls.tran_flag[0]	== '0'		&&
			    //posls.saf_flag[0]	== '0'		&&
			    //posls.tran_type== pb->Tran_type	&&
			    !strcmp(posls.auth_no, pb->Auth_no)		&&
			    !strcmp(posls.snd_bank_id, pb->Snd_bank_id) &&
			    !strcmp(posls.snd_host_id, pb->Snd_host_id) &&
			    !strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
			}
			else
				break;
#endif
		
		case OFFLINE:
		//在OFFLINE交易中查找是否有该交易的预授权交易,授权号
			if (posls.tran_flag[0]	== '0'		&&
			    posls.saf_flag[0]	== '0'		&&
			    posls.tran_type	== PRE_AUTH	&&
			    !strcmp(posls.auth_no, pb->Auth_no)		&&
			    !strcmp(posls.resp_code, SUCCESS)){
					EXEC SQL CLOSE sel_tran_ls_cur;
					memcpy( po, &posls, sizeof( S_tran_ls ) );
					return 0;
			}
			else
				break;
		
		default:
			errcall(ERROR, "不处理该交易[%d]", pb->Tran_type);
			return -1;

		}//end of switch()
	}//end of while(1)
}


/***************************************************************
功能:
	用于查询 cur_tran_ls, his_tran_ls, err_tran_ls 表中
	唯一记录 --> po

ENTRY:		sqlstr		格式必须为: select * from 
RETURN:		-1	FAIL
		0	FOUND,RESULT ---> po
		-2	NOT FOUND
****************************************************************/
int select_ls_record( sqlstring, po )
char			*sqlstring;
S_tran_ls		*po;
{

EXEC SQL BEGIN DECLARE SECTION;
char		sqlstr[1024];
S_tran_ls	l_tran_ls;
EXEC SQL END DECLARE SECTION;


	if (strlen(sqlstring) > 1024)
		return -1;
	strcpy(sqlstr, sqlstring);

	EXEC SQL PREPARE sel_posls FROM :sqlstr;
	EXEC SQL DECLARE sel_ls1 CURSOR WITH HOLD FOR sel_posls;
	if( SQLCODE < 0 ) {
		errcall(ERROR, "DECLARE数据库游标失败[%ld][%s]", SQLCODE, sqlstr);
		return -1;
	}

	EXEC SQL OPEN sel_ls1;
	if( SQLCODE < 0 ) {
		errcall(ERROR, "OPEN数据库游标失败[%ld][%s]", SQLCODE, sqlstr);
		return -1;
	}

	EXEC SQL FETCH sel_ls1 INTO 	:l_tran_ls; 
	if( SQLCODE < 0 ) {
		errcall(ERROR, "Fetch数据库游标失败[%ld][%s]", SQLCODE, sqlstr);
		EXEC SQL CLOSE sel_ls1;
		return -1;
	}

	if( SQLCODE == SQLNOTFOUND ) {
		errcall(DEBUG, "没有找到交易的流水信息!!");
		EXEC SQL CLOSE sel_ls1;
		return -2;
	}

	EXEC SQL CLOSE sel_ls1;

	del_st_space("cur_tran_ls", &l_tran_ls);
	memcpy(po, &l_tran_ls, sizeof(S_tran_ls));

	return 0;
}

/***************************************************************
功能:
	对任意表的更新
ENTRY:	sqlstring
RETURN:	-1	FAIL
	0	SUCC
	1	NOTFOUND
****************************************************************/
int update_table( sqlstring )
char	*sqlstring;
{

EXEC SQL BEGIN DECLARE SECTION;
char		sqlstr[1024];
EXEC SQL END DECLARE SECTION;

	if (strlen(sqlstring) > 1024)
		return -1;
	strcpy( sqlstr, sqlstring );

	EXEC SQL EXECUTE IMMEDIATE :sqlstr; 
	if (SQLCODE) {
		if (SQLCODE == SQLNOTFOUND){
			errcall(DEBUG, "更新数据库没找到[%s]", sqlstr);
			return 1;
		};
		errcall(ERROR, "更新数据库失败[%d][%s]", SQLCODE, sqlstr);
		return -1;
	}
	if (sqlca.sqlerrd[2] == 0) {
		errcall(DEBUG, "更新数据库没找到[%s]", sqlstr);
		return 1;
	}

	return 0;
}

/***************************************************************
功能:
	取本地系统参数表信息
ENTRY:	NULL
RETURN:	-1	FAIL
	0	SUCC, RESULT --> sy
****************************************************************/
int select_sys_param( sy )
S_sys_param	*sy;
{
EXEC SQL BEGIN DECLARE SECTION;
S_sys_param	l_sys_param;
EXEC SQL END DECLARE SECTION;

	EXEC SQL SELECT DISTINCT * INTO :l_sys_param FROM sys_param;
	if (SQLCODE) {
		errcall(ERROR, "取系统参数表失败![%ld]", SQLCODE);
		return -1;
	}

	del_st_space("sys_param", &l_sys_param);
	memcpy(sy, &l_sys_param, sizeof(S_sys_param));

	return 0;
}

/***************************************************************
功能:
	联行行号比较

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -