고도화: 전 모듈 dbio 25→40 · batch 17→22 세분화 (+432본, 전부 고유)

- 11개 모듈 각 dbio +15(→40), batch +5(→22) 새 고유 ECPG 프로그램 + 카피북 헤더
  (window/HAVING/JOIN/FILTER/NOT EXISTS/upsert/correlated/INSERT..SELECT 등 구조 다양)
- 전 코퍼스 .pgc 1004/1004 정규화-고유 (dup 그룹 0)
- 통합 검증: 12서버 runok, 333 서비스, 242 배치 바이너리, 매입체인 XA 커밋, prepared_xacts=0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
forge-bot 2026-07-19 14:37:10 +00:00
parent 05ad8a3064
commit fc16ea64c8
422 changed files with 8717 additions and 0 deletions

View file

@ -0,0 +1,11 @@
/*
* mg_abovavg_dbio.h - mg DB copybook (mg_abovavg_dbio). ( avg).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_ABOVAVG_DBIO_H
#define MG_ABOVAVG_DBIO_H
long mgdb_above_chan_avg(const char *bizdate);
#endif /* MG_ABOVAVG_DBIO_H */

View file

@ -0,0 +1,23 @@
/*
* mg_abovavg_dbio.pgc - mg 모듈 DB 접근 함수 (mg_abovavg_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 채널 평균금액을 초과한 전문 건수 (상관 서브쿼리 avg).
*/
#include <string.h>
#include <userlog.h>
#include "mg_abovavg_dbio.h"
long mgdb_above_chan_avg(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_v = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL SELECT count(*) INTO :h_v FROM mg_msg_log m
WHERE m.biz_date = :h_bizdate
AND m.amount > (SELECT avg(m2.amount) FROM mg_msg_log m2
WHERE m2.channel = m.channel AND m2.biz_date = :h_bizdate);
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

@ -0,0 +1,11 @@
/*
* mg_ackpurge_batch.h - mg mg_ackpurge_batch (copybook). mg
* + . Included by mg_ackpurge_batch.pgc.
*/
#ifndef MG_ACKPURGE_BATCH_H
#define MG_ACKPURGE_BATCH_H
typedef struct { long deleted; } mg_ackpurge_rec_t;
#define MG_ACKPURGE_CUTOFF "2026-07-01"
#endif /* MG_ACKPURGE_BATCH_H */

View file

@ -0,0 +1,11 @@
/*
* mg_ackpurge_dbio.h - mg DB copybook (mg_ackpurge_dbio). (D) (DELETE ).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_ACKPURGE_DBIO_H
#define MG_ACKPURGE_DBIO_H
long mgdb_purge_acked(const char *cutoff);
#endif /* MG_ACKPURGE_DBIO_H */

View file

@ -0,0 +1,20 @@
/*
* mg_ackpurge_dbio.pgc - mg 모듈 DB 접근 함수 (mg_ackpurge_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 기준일 이전 완료(D) 큐 삭제 후 삭제건수 반환 (DELETE 범위).
*/
#include <string.h>
#include <userlog.h>
#include "mg_ackpurge_dbio.h"
long mgdb_purge_acked(const char *cutoff)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_cut[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_cut, cutoff, sizeof(h_cut)-1); h_cut[sizeof(h_cut)-1] = 0;
EXEC SQL DELETE FROM mg_queue
WHERE biz_date < :h_cut AND status = 'D';
if (sqlca.sqlcode < 0) { userlog("mgdb_purge_acked FAIL [%d]", sqlca.sqlcode); return -1; }
return (long) sqlca.sqlerrd[2];
}

View file

@ -0,0 +1,11 @@
/*
* mg_chdistinct_dbio.h - mg DB copybook (mg_chdistinct_dbio). 2 (count DISTINCT + ).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_CHDISTINCT_DBIO_H
#define MG_CHDISTINCT_DBIO_H
long mgdb_chan_mti_distinct(const char *bizdate);
#endif /* MG_CHDISTINCT_DBIO_H */

View file

@ -0,0 +1,23 @@
/*
* mg_chdistinct_dbio.pgc - mg 모듈 DB 접근 함수 (mg_chdistinct_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 2건 이상 전문이 오간 고유 채널 수 (count DISTINCT + 서브셀렉트).
*/
#include <string.h>
#include <userlog.h>
#include "mg_chdistinct_dbio.h"
long mgdb_chan_mti_distinct(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_v = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL SELECT count(DISTINCT channel) INTO :h_v FROM mg_msg_log
WHERE biz_date = :h_bizdate
AND channel IN (SELECT channel FROM mg_msg_log
WHERE biz_date = :h_bizdate GROUP BY channel HAVING count(*) >= 2);
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

@ -0,0 +1,11 @@
/*
* mg_dircase_dbio.h - mg DB copybook (mg_dircase_dbio). (IN +, OUT -) - CASE .
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_DIRCASE_DBIO_H
#define MG_DIRCASE_DBIO_H
long mgdb_dir_case_amount(const char *bizdate);
#endif /* MG_DIRCASE_DBIO_H */

View file

@ -0,0 +1,24 @@
/*
* mg_dircase_dbio.pgc - mg 모듈 DB 접근 함수 (mg_dircase_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 방향별 부호가중 금액합 (IN +, OUT -) - CASE 식.
*/
#include <string.h>
#include <userlog.h>
#include "mg_dircase_dbio.h"
long mgdb_dir_case_amount(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_v = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL SELECT coalesce(sum(CASE direction
WHEN 'IN' THEN amount
WHEN 'OUT' THEN -amount
ELSE 0 END), 0)
INTO :h_v FROM mg_msg_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

@ -0,0 +1,10 @@
/*
* mg_mtierr_batch.h - mg mg_mtierr_batch (copybook). mg MTI
* + . Included by mg_mtierr_batch.pgc.
*/
#ifndef MG_MTIERR_BATCH_H
#define MG_MTIERR_BATCH_H
typedef struct { long threshold; long groups; } mg_mtierr_rec_t;
#endif /* MG_MTIERR_BATCH_H */

View file

@ -0,0 +1,11 @@
/*
* mg_mtigroup_dbio.h - mg DB copybook (mg_mtigroup_dbio). (MTI) (GROUP BY HAVING ).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_MTIGROUP_DBIO_H
#define MG_MTIGROUP_DBIO_H
long mgdb_mti_err_groups(const char *bizdate, long minc);
#endif /* MG_MTIGROUP_DBIO_H */

View file

@ -0,0 +1,32 @@
/*
* mg_mtigroup_dbio.pgc - mg 모듈 DB 접근 함수 (mg_mtigroup_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 임계 이상 응답오류가 난 전문유형(MTI) 그룹 수 (GROUP BY HAVING 커서).
*/
#include <string.h>
#include <userlog.h>
#include "mg_mtigroup_dbio.h"
long mgdb_mti_err_groups(const char *bizdate, long minc)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_mti[8];
long h_min, h_cnt, groups = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
h_min = minc;
EXEC SQL DECLARE meg CURSOR FOR
SELECT mti, count(*) FROM mg_msg_log
WHERE biz_date = :h_bizdate AND rc <> '00'
GROUP BY mti HAVING count(*) >= :h_min;
EXEC SQL OPEN meg;
if (sqlca.sqlcode < 0) { userlog("mgdb_mti_err_groups OPEN [%d]", sqlca.sqlcode); return -1; }
for (;;) {
EXEC SQL FETCH meg INTO :h_mti, :h_cnt;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE meg; return -1; }
groups++;
}
EXEC SQL CLOSE meg;
return groups;
}

View file

@ -0,0 +1,11 @@
/*
* mg_nackfilter_dbio.h - mg DB copybook (mg_nackfilter_dbio). NACK(status=N) (bps) - FILTER .
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_NACKFILTER_DBIO_H
#define MG_NACKFILTER_DBIO_H
long mgdb_nack_filter(const char *bizdate);
#endif /* MG_NACKFILTER_DBIO_H */

View file

@ -0,0 +1,22 @@
/*
* mg_nackfilter_dbio.pgc - mg 모듈 DB 접근 함수 (mg_nackfilter_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 전체 대비 NACK(status=N) 비율(bps) - FILTER 절.
*/
#include <string.h>
#include <userlog.h>
#include "mg_nackfilter_dbio.h"
long mgdb_nack_filter(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_nack = 0, h_tot = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL SELECT count(*) FILTER (WHERE status = 'N'), count(*)
INTO :h_nack, :h_tot FROM mg_msg_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) return -1;
if (h_tot <= 0) return 0;
return h_nack * 10000 / h_tot;
}

View file

@ -0,0 +1,11 @@
/*
* mg_qforup_dbio.h - mg DB copybook (mg_qforup_dbio). UP (IN ).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_QFORUP_DBIO_H
#define MG_QFORUP_DBIO_H
long mgdb_queue_for_up(const char *bizdate);
#endif /* MG_QFORUP_DBIO_H */

View file

@ -0,0 +1,22 @@
/*
* mg_qforup_dbio.pgc - mg 모듈 DB 접근 함수 (mg_qforup_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* UP 상태 채널에 걸린 대기 큐 건수 (IN 서브셀렉트).
*/
#include <string.h>
#include <userlog.h>
#include "mg_qforup_dbio.h"
long mgdb_queue_for_up(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_v = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL SELECT count(*) INTO :h_v FROM mg_queue
WHERE biz_date = :h_bizdate AND status = 'Q'
AND channel IN (SELECT channel FROM mg_channel WHERE status = 'UP');
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

@ -0,0 +1,10 @@
/*
* mg_rankamt_batch.h - mg mg_rankamt_batch (copybook). mg
* + . Included by mg_rankamt_batch.pgc.
*/
#ifndef MG_RANKAMT_BATCH_H
#define MG_RANKAMT_BATCH_H
typedef struct { long scanned; long tops; } mg_rankamt_rec_t;
#endif /* MG_RANKAMT_BATCH_H */

View file

@ -0,0 +1,11 @@
/*
* mg_rankamt_dbio.h - mg DB copybook (mg_rankamt_dbio). (1) (ROW_NUMBER ).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_RANKAMT_DBIO_H
#define MG_RANKAMT_DBIO_H
long mgdb_rank_by_amount(const char *bizdate);
#endif /* MG_RANKAMT_DBIO_H */

View file

@ -0,0 +1,31 @@
/*
* mg_rankamt_dbio.pgc - mg 모듈 DB 접근 함수 (mg_rankamt_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 채널별 최고금액(랭크1) 전문 수 (ROW_NUMBER 윈도우 커서).
*/
#include <string.h>
#include <userlog.h>
#include "mg_rankamt_dbio.h"
long mgdb_rank_by_amount(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_mid, h_rn, tops = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL DECLARE mrk CURSOR FOR
SELECT msg_id,
ROW_NUMBER() OVER (PARTITION BY channel ORDER BY amount DESC)
FROM mg_msg_log WHERE biz_date = :h_bizdate;
EXEC SQL OPEN mrk;
if (sqlca.sqlcode < 0) return -1;
for (;;) {
EXEC SQL FETCH mrk INTO :h_mid, :h_rn;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE mrk; return -1; }
if (h_rn == 1) tops++;
}
EXEC SQL CLOSE mrk;
return tops;
}

View file

@ -0,0 +1,11 @@
/*
* mg_reqfail_dbio.h - mg DB copybook (mg_reqfail_dbio). (rc<>00) (INSERT..SELECT).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_REQFAIL_DBIO_H
#define MG_REQFAIL_DBIO_H
long mgdb_enqueue_failed(const char *bizdate);
#endif /* MG_REQFAIL_DBIO_H */

View file

@ -0,0 +1,23 @@
/*
* mg_reqfail_dbio.pgc - mg 모듈 DB 접근 함수 (mg_reqfail_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 응답오류(rc<>00) 전문을 재전송 큐로 적재 (INSERT..SELECT).
*/
#include <string.h>
#include <userlog.h>
#include "mg_reqfail_dbio.h"
long mgdb_enqueue_failed(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL INSERT INTO mg_queue
(queue_id, stan, channel, mti, payload, status, biz_date)
SELECT nextval('mg_queue_seq'), m.stan, m.channel, m.mti, m.raw_msg, 'Q', m.biz_date
FROM mg_msg_log m
WHERE m.biz_date = :h_bizdate AND m.rc <> '00' AND m.direction = 'IN';
if (sqlca.sqlcode < 0) { userlog("mgdb_enqueue_failed FAIL [%d]", sqlca.sqlcode); return -1; }
return (long) sqlca.sqlerrd[2];
}

View file

@ -0,0 +1,10 @@
/*
* mg_requeue_batch.h - mg mg_requeue_batch (copybook). mg
* + . Included by mg_requeue_batch.pgc.
*/
#ifndef MG_REQUEUE_BATCH_H
#define MG_REQUEUE_BATCH_H
typedef struct { long requeued; } mg_requeue_rec_t;
#endif /* MG_REQUEUE_BATCH_H */

View file

@ -0,0 +1,11 @@
/*
* mg_routegrp_dbio.h - mg DB copybook (mg_routegrp_dbio). (JOIN + GROUP BY ).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_ROUTEGRP_DBIO_H
#define MG_ROUTEGRP_DBIO_H
long mgdb_route_amount_groups(const char *bizdate);
#endif /* MG_ROUTEGRP_DBIO_H */

View file

@ -0,0 +1,32 @@
/*
* mg_routegrp_dbio.pgc - mg 모듈 DB 접근 함수 (mg_routegrp_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 라우팅 매칭 전문의 목적지별 최대 금액그룹 수 (JOIN + GROUP BY 커서).
*/
#include <string.h>
#include <userlog.h>
#include "mg_routegrp_dbio.h"
long mgdb_route_amount_groups(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_dest[64];
long h_sum, groups = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL DECLARE mrg CURSOR FOR
SELECT r.dest, coalesce(sum(m.amount),0)
FROM mg_msg_log m JOIN mg_route r ON r.channel = m.channel AND r.mti = m.mti
WHERE m.biz_date = :h_bizdate AND r.active
GROUP BY r.dest;
EXEC SQL OPEN mrg;
if (sqlca.sqlcode < 0) return -1;
for (;;) {
EXEC SQL FETCH mrg INTO :h_dest, :h_sum;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE mrg; return -1; }
groups++;
}
EXEC SQL CLOSE mrg;
return groups;
}

View file

@ -0,0 +1,11 @@
/*
* mg_stanrange_dbio.h - mg DB copybook (mg_stanrange_dbio). (STAN) - (min/max).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_STANRANGE_DBIO_H
#define MG_STANRANGE_DBIO_H
long mgdb_stan_spread(const char *bizdate);
#endif /* MG_STANRANGE_DBIO_H */

View file

@ -0,0 +1,21 @@
/*
* mg_stanrange_dbio.pgc - mg 모듈 DB 접근 함수 (mg_stanrange_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 당일 전문 추적번호(STAN) 최대-최소 범위 (min/max).
*/
#include <string.h>
#include <userlog.h>
#include "mg_stanrange_dbio.h"
long mgdb_stan_spread(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_lo = 0, h_hi = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL SELECT coalesce(min(stan),0), coalesce(max(stan),0)
INTO :h_lo, :h_hi FROM mg_msg_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) return -1;
return h_hi - h_lo;
}

View file

@ -0,0 +1,10 @@
/*
* mg_unrouted_batch.h - mg mg_unrouted_batch (copybook). mg
* + . Included by mg_unrouted_batch.pgc.
*/
#ifndef MG_UNROUTED_BATCH_H
#define MG_UNROUTED_BATCH_H
typedef struct { long unrouted; } mg_unrouted_rec_t;
#endif /* MG_UNROUTED_BATCH_H */

View file

@ -0,0 +1,11 @@
/*
* mg_unrouted_dbio.h - mg DB copybook (mg_unrouted_dbio). (NOT EXISTS mg_route).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef MG_UNROUTED_DBIO_H
#define MG_UNROUTED_DBIO_H
long mgdb_unrouted_msgs(const char *bizdate);
#endif /* MG_UNROUTED_DBIO_H */

View file

@ -0,0 +1,23 @@
/*
* mg_unrouted_dbio.pgc - mg 모듈 DB 접근 함수 (mg_unrouted_dbio), archived into libmgdbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 라우팅 룰이 없는 전문 건수 (NOT EXISTS mg_route).
*/
#include <string.h>
#include <userlog.h>
#include "mg_unrouted_dbio.h"
long mgdb_unrouted_msgs(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_v = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL SELECT count(*) INTO :h_v FROM mg_msg_log m
WHERE m.biz_date = :h_bizdate
AND NOT EXISTS (SELECT 1 FROM mg_route r
WHERE r.channel = m.channel AND r.mti = m.mti AND r.active);
if (sqlca.sqlcode < 0) return -1;
return h_v;
}