?? db_op.ec.std
字號:
/*========================================================================
功能: 對數據庫表操作
作者:
王永忠: 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 + -