Phase 2c 마무리: 전 코퍼스 793/793 고유 (클론 0) + au/py run 완성

- au/py dbio/batch/run 확장 마무리 (svc30·dbio25·batch17·run17)
- cm/mg 배치 + mm/vl dbio 크로스모듈 클론 32개 → 각각 고유 SQL 구조로 재작성
- 전 .pgc 793/793 정규화-고유(클론 그룹 0)
- 통합 재검증: 12서버 runok, 333 서비스 AVAIL, 매입체인 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 12:18:11 +00:00
parent fd8b418c6e
commit 05ad8a3064
32 changed files with 258 additions and 198 deletions

View file

@ -1,8 +1,9 @@
/* /*
* cm_archive_batch.pgc - cm 모듈 상태 일괄 전이 업데이트 배치 (XA). * cm_archive_batch.pgc - cm 정보(I) 로그 보관(A) 전이 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 상태 일괄 전이 업데이트; then tpcommit drives XA 2PC. * transaction; 해당 영업일 정보 로그 중 log_id 오름차순 앞 5000건을 보관(A)
* 상태로 전이(UPDATE ... WHERE log_id IN (서브셀렉트 ORDER BY LIMIT)); tpcommit.
* Usage: cm_archive_batch [YYYY-MM-DD] * Usage: cm_archive_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,13 +26,15 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL UPDATE cm_log SET log_level = 'A', updated_at = now() EXEC SQL UPDATE cm_log SET log_level = 'A'
WHERE biz_date = :h_bizdate AND log_level = 'I'; WHERE log_id IN (SELECT log_id FROM cm_log
WHERE biz_date = :h_bizdate AND log_level = 'I'
ORDER BY log_id LIMIT 5000);
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_archive_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_archive_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_upd = sqlca.sqlerrd[2]; h_upd = sqlca.sqlerrd[2];
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_archive_batch COMMIT: bizdate=%s updated=%ld\n", bizdate, h_upd); printf(">>> cm_archive_batch COMMIT: bizdate=%s archived=%ld\n", bizdate, h_upd);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_dbgpurge_batch.pgc - cm 모듈 상태 조건 삭제 배치 (XA). * cm_dbgpurge_batch.pgc - cm 디버그/추적 로그 정리 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 상태 조건 삭제; then tpcommit drives XA 2PC. * transaction; 기준 영업일 이전(<)의 디버그(D)/추적(T) 로그를 한 번의
* DELETE (OR 조건 그룹) 로 정리; then tpcommit drives XA 2PC.
* Usage: cm_dbgpurge_batch [YYYY-MM-DD] * Usage: cm_dbgpurge_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,7 +26,8 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DELETE FROM cm_log WHERE biz_date = :h_bizdate AND log_level = 'D'; EXEC SQL DELETE FROM cm_log
WHERE biz_date < :h_bizdate AND (log_level = 'D' OR log_level = 'T');
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_dbgpurge_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_dbgpurge_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_del = sqlca.sqlerrd[2]; h_del = sqlca.sqlerrd[2];

View file

@ -1,8 +1,9 @@
/* /*
* cm_distinct_batch.pgc - cm 모듈 고유값(distinct) 집계 배치 (XA). * cm_distinct_batch.pgc - cm 반복 서비스(로그 2건 이상) 수 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 고유값(distinct) 집계; then tpcommit drives XA 2PC. * transaction; 해당 영업일에 로그가 2건 이상인 서비스 수를 FROM 서브쿼리
* (GROUP BY ... HAVING count(*)>1) 를 다시 count 하여 산출; then tpcommit.
* Usage: cm_distinct_batch [YYYY-MM-DD] * Usage: cm_distinct_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,11 +26,13 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(DISTINCT svc_name) INTO :h_d FROM cm_log WHERE biz_date = :h_bizdate; EXEC SQL SELECT count(*) INTO :h_d FROM
(SELECT svc_name FROM cm_log WHERE biz_date = :h_bizdate
GROUP BY svc_name HAVING count(*) > 1) t;
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_distinct_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_distinct_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_distinct_batch COMMIT: bizdate=%s distinct=%ld\n", bizdate, h_d); printf(">>> cm_distinct_batch COMMIT: bizdate=%s repeated_svc=%ld\n", bizdate, h_d);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_errbps_batch.pgc - cm 모듈 두 SELECT 비율(bps) 산출 배치 (XA). * cm_errbps_batch.pgc - cm 오류 로그 비율(bps) 산출 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 두 SELECT 비율(bps) 산출; then tpcommit drives XA 2PC. * transaction; 단일 SELECT 에서 count(*) FILTER (WHERE ...) 로 오류(E) 건과
* 전체 건을 동시에 집계한 뒤 C 에서 bps 를 계산; then tpcommit drives XA 2PC.
* Usage: cm_errbps_batch [YYYY-MM-DD] * Usage: cm_errbps_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_a = 0, h_b = 0, h_bps = 0; long h_err = 0, h_tot = 0, h_bps = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,15 +26,13 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_a FROM cm_log EXEC SQL SELECT count(*) FILTER (WHERE log_level = 'E'), count(*)
WHERE biz_date = :h_bizdate AND log_level = 'E'; INTO :h_err, :h_tot FROM cm_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_errbps_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
EXEC SQL SELECT count(*) INTO :h_b FROM cm_log WHERE biz_date = :h_bizdate; h_bps = (h_tot > 0) ? h_err * 10000 / h_tot : 0;
if (sqlca.sqlcode < 0) { tpabort(0); return 1; }
h_bps = (h_b > 0) ? h_a * 10000 / h_b : 0;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_errbps_batch COMMIT: bizdate=%s hit=%ld total=%ld bps=%ld\n", bizdate, h_a, h_b, h_bps); printf(">>> cm_errbps_batch COMMIT: bizdate=%s err=%ld total=%ld bps=%ld\n", bizdate, h_err, h_tot, h_bps);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_fxjoin_batch.pgc - cm 모듈 조인 집계 배치 (XA). * cm_fxjoin_batch.pgc - cm 환율 x 통화코드 조인 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 조인 집계; then tpcommit drives XA 2PC. * transaction; cm_fx_rate 를 cm_code(CCY 그룹)와 조인하여 등록 통화의 환율
* 합계와 고유 통화 수(count DISTINCT)를 한 행으로 집계; then tpcommit.
* Usage: cm_fxjoin_batch [YYYY-MM-DD] * Usage: cm_fxjoin_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_v = 0; long h_sum = 0, h_ccy = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,13 +26,14 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(sum(a.rate_bps),0) INTO :h_v EXEC SQL SELECT coalesce(sum(r.rate_bps),0), count(DISTINCT r.ccy)
FROM cm_fx_rate a JOIN cm_holiday b ON a.base_date = b.holi_date INTO :h_sum, :h_ccy
WHERE a.base_date = :h_bizdate; FROM cm_fx_rate r JOIN cm_code c ON r.ccy = c.code
WHERE r.base_date = :h_bizdate AND c.code_grp = 'CCY';
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_fxjoin_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_fxjoin_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_fxjoin_batch COMMIT: bizdate=%s joined_sum=%ld\n", bizdate, h_v); printf(">>> cm_fxjoin_batch COMMIT: bizdate=%s rate_sum=%ld ccy=%ld\n", bizdate, h_sum, h_ccy);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_fxspread_batch.pgc - cm 모듈 최대-최소 스프레드 집계 배치 (XA). * cm_fxspread_batch.pgc - cm 환율 최대/최소/평균 분포 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 최대-최소 스프레드 집계; then tpcommit drives XA 2PC. * transaction; 기준일 환율의 max/min/avg(3개 집계, avg 는 CAST ... AS BIGINT)
* 를 한 행으로 뽑아 C 에서 스프레드(max-min)를 계산; then tpcommit.
* Usage: cm_fxspread_batch [YYYY-MM-DD] * Usage: cm_fxspread_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_max = 0, h_min = 0, h_spread = 0; long h_max = 0, h_min = 0, h_avg = 0, h_spread = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,13 +26,14 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(max(rate_bps),0), coalesce(min(rate_bps),0) EXEC SQL SELECT coalesce(max(rate_bps),0), coalesce(min(rate_bps),0),
INTO :h_max, :h_min FROM cm_fx_rate WHERE base_date = :h_bizdate; CAST(coalesce(avg(rate_bps),0) AS BIGINT)
INTO :h_max, :h_min, :h_avg FROM cm_fx_rate WHERE base_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_fxspread_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_fxspread_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_spread = h_max - h_min; h_spread = h_max - h_min;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_fxspread_batch COMMIT: bizdate=%s max=%ld min=%ld spread=%ld\n", bizdate, h_max, h_min, h_spread); printf(">>> cm_fxspread_batch COMMIT: bizdate=%s max=%ld min=%ld avg=%ld spread=%ld\n", bizdate, h_max, h_min, h_avg, h_spread);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_fxsum_batch.pgc - cm 모듈 스칼라 합계 집계 배치 (XA). * cm_fxsum_batch.pgc - cm 외화(비원화) 환율 합계/건수 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 스칼라 합계 집계; then tpcommit drives XA 2PC. * transaction; 기준일 환율 중 원화(KRW)를 제외(<>)한 통화의 rate_bps 합계와
* 건수를 한 행으로 집계; then tpcommit drives XA 2PC.
* Usage: cm_fxsum_batch [YYYY-MM-DD] * Usage: cm_fxsum_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_v = 0; long h_sum = 0, h_cnt = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,11 +26,12 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(sum(rate_bps),0) INTO :h_v FROM cm_fx_rate WHERE base_date = :h_bizdate; EXEC SQL SELECT coalesce(sum(rate_bps),0), count(*) INTO :h_sum, :h_cnt
FROM cm_fx_rate WHERE base_date = :h_bizdate AND ccy <> 'KRW';
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_fxsum_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_fxsum_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_fxsum_batch COMMIT: bizdate=%s total=%ld\n", bizdate, h_v); printf(">>> cm_fxsum_batch COMMIT: bizdate=%s fx_sum=%ld ccy_cnt=%ld\n", bizdate, h_sum, h_cnt);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_levelstat_batch.pgc - cm 모듈 3분류 CASE 집계 배치 (XA). * cm_levelstat_batch.pgc - cm 로그 레벨 4분류 CASE 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 3분류 CASE 집계; then tpcommit drives XA 2PC. * transaction; 정보(I)/경고(W)/오류(E)/기타(NOT IN) 4개 CASE 합계를 한 행으로
* 집계; then tpcommit drives XA 2PC.
* Usage: cm_levelstat_batch [YYYY-MM-DD] * Usage: cm_levelstat_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_a = 0, h_b = 0, h_c = 0; long h_i = 0, h_w = 0, h_e = 0, h_o = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -28,12 +29,13 @@ int main(int argc, char **argv)
EXEC SQL SELECT EXEC SQL SELECT
coalesce(sum(CASE WHEN log_level = 'I' THEN 1 ELSE 0 END),0), coalesce(sum(CASE WHEN log_level = 'I' THEN 1 ELSE 0 END),0),
coalesce(sum(CASE WHEN log_level = 'W' THEN 1 ELSE 0 END),0), coalesce(sum(CASE WHEN log_level = 'W' THEN 1 ELSE 0 END),0),
coalesce(sum(CASE WHEN log_level = 'E' THEN 1 ELSE 0 END),0) coalesce(sum(CASE WHEN log_level = 'E' THEN 1 ELSE 0 END),0),
INTO :h_a, :h_b, :h_c FROM cm_log WHERE biz_date = :h_bizdate; coalesce(sum(CASE WHEN log_level NOT IN ('I','W','E') THEN 1 ELSE 0 END),0)
INTO :h_i, :h_w, :h_e, :h_o FROM cm_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_levelstat_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_levelstat_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_levelstat_batch COMMIT: bizdate=%s a=%ld b=%ld c=%ld\n", bizdate, h_a, h_b, h_c); printf(">>> cm_levelstat_batch COMMIT: bizdate=%s i=%ld w=%ld e=%ld other=%ld\n", bizdate, h_i, h_w, h_e, h_o);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_logcnt_batch.pgc - cm 모듈 건수+금액 단건 집계 배치 (XA). * cm_logcnt_batch.pgc - cm 로그 건수/합계/최대 log_id 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 건수+금액 단건 집계; then tpcommit drives XA 2PC. * transaction; 기준일 로그의 건수 + log_id 합계 + 최대 log_id(3개 집계)를 한
* 행으로 산출; then tpcommit drives XA 2PC.
* Usage: cm_logcnt_batch [YYYY-MM-DD] * Usage: cm_logcnt_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_cnt = 0, h_sum = 0; long h_cnt = 0, h_sum = 0, h_max = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,12 +26,12 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*), coalesce(sum(log_id),0) INTO :h_cnt, :h_sum EXEC SQL SELECT count(*), coalesce(sum(log_id),0), coalesce(max(log_id),0)
FROM cm_log WHERE biz_date = :h_bizdate; INTO :h_cnt, :h_sum, :h_max FROM cm_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_logcnt_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_logcnt_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_logcnt_batch COMMIT: bizdate=%s rows=%ld sum=%ld\n", bizdate, h_cnt, h_sum); printf(">>> cm_logcnt_batch COMMIT: bizdate=%s rows=%ld sum=%ld max_id=%ld\n", bizdate, h_cnt, h_sum, h_max);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_logprune_batch.pgc - cm 모듈 서브셀렉트 IN 조건 삭제 배치 (XA). * cm_logprune_batch.pgc - cm 비휴일 디버그 로그 정리 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 서브셀렉트 IN 조건 삭제; then tpcommit drives XA 2PC. * transaction; 기준일 이하(<=)의 디버그(D) 로그 중 휴일(cm_holiday)이 아닌
* (NOT EXISTS 상관 서브쿼리) 날짜의 로그를 삭제; then tpcommit.
* Usage: cm_logprune_batch [YYYY-MM-DD] * Usage: cm_logprune_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -26,7 +27,8 @@ int main(int argc, char **argv)
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DELETE FROM cm_log EXEC SQL DELETE FROM cm_log
WHERE log_id IN (SELECT log_id FROM cm_log WHERE biz_date = :h_bizdate AND log_level = 'D'); WHERE log_level = 'D' AND biz_date <= :h_bizdate
AND NOT EXISTS (SELECT 1 FROM cm_holiday h WHERE h.holi_date = cm_log.biz_date);
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_logprune_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_logprune_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_del = sqlca.sqlerrd[2]; h_del = sqlca.sqlerrd[2];

View file

@ -1,8 +1,9 @@
/* /*
* cm_logroll_batch.pgc - cm 모듈 INSERT ... SELECT 그룹 롤업 적재 배치 (XA). * cm_logroll_batch.pgc - cm 서비스별 로그 롤업 요약행 적재 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; INSERT ... SELECT 그룹 롤업 적재; then tpcommit drives XA 2PC. * transaction; 기준일 로그를 서비스별로 GROUP BY ... HAVING count(*)>0 집계하여
* 서비스당 요약(S) 로그 한 건씩을 INSERT ... SELECT 로 재적재; then tpcommit.
* Usage: cm_logroll_batch [YYYY-MM-DD] * Usage: cm_logroll_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,9 +26,10 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL INSERT INTO cm_log_rollup (svc_name, biz_date, cnt, amt) EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
SELECT svc_name, biz_date, count(*), coalesce(sum(log_id),0) SELECT nextval('cm_log_seq'), svc_name, 'S', 'ROLLUP', :h_bizdate
FROM cm_log WHERE biz_date = :h_bizdate GROUP BY svc_name, biz_date; FROM cm_log WHERE biz_date = :h_bizdate
GROUP BY svc_name HAVING count(*) > 0;
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_logroll_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_logroll_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_rows = sqlca.sqlerrd[2]; h_rows = sqlca.sqlerrd[2];

View file

@ -1,8 +1,9 @@
/* /*
* cm_marker_batch.pgc - cm 모듈 시퀀스 채번 + 마커 행 INSERT 배치 (XA). * cm_marker_batch.pgc - cm 일마감 마커 로그 적재 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 시퀀스 채번 + 마커 행 INSERT; then tpcommit drives XA 2PC. * transaction; 기준일 로그의 건수와 최대 log_id 를 집계한 뒤, cm_log 에 마감
* 마커(I) 한 건을 nextval 채번으로 직접 INSERT(VALUES); then tpcommit.
* Usage: cm_marker_batch [YYYY-MM-DD] * Usage: cm_marker_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_id = 0, h_cnt = 0; long h_cnt = 0, h_max = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,15 +26,15 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM cm_log WHERE biz_date = :h_bizdate; EXEC SQL SELECT count(*), coalesce(max(log_id),0) INTO :h_cnt, :h_max
FROM cm_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } if (sqlca.sqlcode < 0) { tpabort(0); return 1; }
EXEC SQL SELECT nextval('cm_log_seq') INTO :h_id; EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } VALUES (nextval('cm_log_seq'), 'EOD', 'I', 'DAY MARK', :h_bizdate);
EXEC SQL INSERT INTO cm_eod_mark (mark_id, biz_date, cnt) VALUES (:h_id, :h_bizdate, :h_cnt);
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_marker_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_marker_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_marker_batch COMMIT: bizdate=%s mark_id=%ld cnt=%ld\n", bizdate, h_id, h_cnt); printf(">>> cm_marker_batch COMMIT: bizdate=%s cnt=%ld max_id=%ld\n", bizdate, h_cnt, h_max);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_reconf_batch.pgc - cm 모듈 건수 확인 후 조건부 업데이트 배치 (XA). * cm_reconf_batch.pgc - cm 경고(W) 로그 조건부 재분류 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 건수 확인 후 조건부 업데이트; then tpcommit drives XA 2PC. * transaction; 경고(W) 로그 건수를 먼저 확인하고, 존재할 때만 msg 내용에 따라
* CASE 로 보관(A)/유지(W)를 결정하는 UPDATE 를 수행; then tpcommit.
* Usage: cm_reconf_batch [YYYY-MM-DD] * Usage: cm_reconf_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -29,14 +30,15 @@ int main(int argc, char **argv)
WHERE biz_date = :h_bizdate AND log_level = 'W'; WHERE biz_date = :h_bizdate AND log_level = 'W';
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } if (sqlca.sqlcode < 0) { tpabort(0); return 1; }
if (h_cnt > 0) { if (h_cnt > 0) {
EXEC SQL UPDATE cm_log SET log_level = 'A', updated_at = now() EXEC SQL UPDATE cm_log
SET log_level = CASE WHEN msg LIKE '%OK%' THEN 'A' ELSE 'W' END
WHERE biz_date = :h_bizdate AND log_level = 'W'; WHERE biz_date = :h_bizdate AND log_level = 'W';
if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_reconf_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "cm_reconf_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_upd = sqlca.sqlerrd[2]; h_upd = sqlca.sqlerrd[2];
} }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_reconf_batch COMMIT: bizdate=%s pending=%ld updated=%ld\n", bizdate, h_cnt, h_upd); printf(">>> cm_reconf_batch COMMIT: bizdate=%s warn=%ld reclassified=%ld\n", bizdate, h_cnt, h_upd);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_svcacc_batch.pgc - cm 모듈 커서 누적 합계 (행별 DML 없음) 배치 (XA). * cm_svcacc_batch.pgc - cm 서비스별 로그 커서 누적/최대 산출 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 커서 누적 합계 (행별 DML 없음); then tpcommit drives XA 2PC. * transaction; 서비스별(건수,log_id 합)을 커서로 순회하며 총건수/총합을 누적
* 하고, C 에서 최대 그룹합(peak)을 if 로 갱신(행별 DML 없음); then tpcommit.
* Usage: cm_svcacc_batch [YYYY-MM-DD] * Usage: cm_svcacc_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,8 +17,9 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_key[32]; char h_bizdate[16], h_key[32];
long h_amt = 0, total = 0, rows = 0; long h_cnt = 0, h_amt = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long tot_cnt = 0, tot_amt = 0, peak = 0, groups = 0;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,21 +27,22 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DECLARE bc CURSOR FOR EXEC SQL DECLARE ac CURSOR FOR
SELECT svc_name, coalesce(sum(log_id),0) FROM cm_log SELECT svc_name, count(*), coalesce(sum(log_id),0) FROM cm_log
WHERE biz_date = :h_bizdate GROUP BY svc_name; WHERE biz_date = :h_bizdate GROUP BY svc_name;
EXEC SQL OPEN bc; EXEC SQL OPEN ac;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
for (;;) { for (;;) {
EXEC SQL FETCH bc INTO :h_key, :h_amt; EXEC SQL FETCH ac INTO :h_key, :h_cnt, :h_amt;
if (sqlca.sqlcode == 100) break; if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bc; tpabort(0); return 1; } if (sqlca.sqlcode < 0) { EXEC SQL CLOSE ac; tpabort(0); return 1; }
total += h_amt; rows++; tot_cnt += h_cnt; tot_amt += h_amt; groups++;
if (h_amt > peak) peak = h_amt;
} }
EXEC SQL CLOSE bc; EXEC SQL CLOSE ac;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_svcacc_batch COMMIT: bizdate=%s groups=%ld total=%ld\n", bizdate, rows, total); printf(">>> cm_svcacc_batch COMMIT: bizdate=%s groups=%ld rows=%ld sum=%ld peak=%ld\n", bizdate, groups, tot_cnt, tot_amt, peak);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* cm_svcsnap_batch.pgc - cm 모듈 커서 순회 후 대상 테이블 행별 INSERT 배치 (XA). * cm_svcsnap_batch.pgc - cm 서비스별 스냅샷 마커 조건부 적재 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 커서 순회 후 대상 테이블 행별 INSERT; then tpcommit drives XA 2PC. * transaction; 서비스별 log_id 합을 커서로 순회하며 합이 0보다 큰 서비스에만
* (if 가드) cm_log 스냅샷(S) 마커를 행별 INSERT; then tpcommit.
* Usage: cm_svcsnap_batch [YYYY-MM-DD] * Usage: cm_svcsnap_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,8 +17,9 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_key[32]; char h_bizdate[16], h_key[32];
long h_amt = 0, rows = 0; long h_amt = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long inserted = 0, skipped = 0;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,24 +27,28 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DECLARE bc CURSOR FOR EXEC SQL DECLARE sc CURSOR FOR
SELECT svc_name, coalesce(sum(log_id),0) FROM cm_log SELECT svc_name, coalesce(sum(log_id),0) FROM cm_log
WHERE biz_date = :h_bizdate GROUP BY svc_name; WHERE biz_date = :h_bizdate GROUP BY svc_name;
EXEC SQL OPEN bc; EXEC SQL OPEN sc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
for (;;) { for (;;) {
EXEC SQL FETCH bc INTO :h_key, :h_amt; EXEC SQL FETCH sc INTO :h_key, :h_amt;
if (sqlca.sqlcode == 100) break; if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bc; tpabort(0); return 1; } if (sqlca.sqlcode < 0) { EXEC SQL CLOSE sc; tpabort(0); return 1; }
EXEC SQL INSERT INTO cm_svc_snap (svc_name, biz_date, amt) if (h_amt > 0) {
VALUES (:h_key, :h_bizdate, :h_amt); EXEC SQL INSERT INTO cm_log (log_id, svc_name, log_level, msg, biz_date)
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bc; tpabort(0); return 1; } VALUES (nextval('cm_log_seq'), :h_key, 'S', 'SNAP', :h_bizdate);
rows++; if (sqlca.sqlcode < 0) { EXEC SQL CLOSE sc; tpabort(0); return 1; }
inserted++;
} else {
skipped++;
} }
EXEC SQL CLOSE bc; }
EXEC SQL CLOSE sc;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cm_svcsnap_batch COMMIT: bizdate=%s inserted=%ld\n", bizdate, rows); printf(">>> cm_svcsnap_batch COMMIT: bizdate=%s inserted=%ld skipped=%ld\n", bizdate, inserted, skipped);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_amount_batch.pgc - mg 모듈 건수+금액 단건 집계 배치 (XA). * mg_amount_batch.pgc - mg 전문 금액 합계/평균 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 건수+금액 단건 집계; then tpcommit drives XA 2PC. * transaction; 기준일 전문의 금액 합계와 평균(CAST avg ... AS BIGINT)을 한
* 행으로 집계; then tpcommit drives XA 2PC.
* Usage: mg_amount_batch [YYYY-MM-DD] * Usage: mg_amount_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_cnt = 0, h_sum = 0; long h_sum = 0, h_avg = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,12 +26,12 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*), coalesce(sum(amount),0) INTO :h_cnt, :h_sum EXEC SQL SELECT coalesce(sum(amount),0), CAST(coalesce(avg(amount),0) AS BIGINT)
FROM mg_msg_log WHERE biz_date = :h_bizdate; INTO :h_sum, :h_avg FROM mg_msg_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_amount_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_amount_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_amount_batch COMMIT: bizdate=%s rows=%ld sum=%ld\n", bizdate, h_cnt, h_sum); printf(">>> mg_amount_batch COMMIT: bizdate=%s sum=%ld avg=%ld\n", bizdate, h_sum, h_avg);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_chanacc_batch.pgc - mg 모듈 커서 누적 합계 (행별 DML 없음) 배치 (XA). * mg_chanacc_batch.pgc - mg 채널별 전문 커서 누적 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 커서 누적 합계 (행별 DML 없음); then tpcommit drives XA 2PC. * transaction; 채널별(건수, 금액합)을 커서로 순회하며 총건수/총금액을 누적만
* 한다(행별 DML/조건분기 없음); then tpcommit drives XA 2PC.
* Usage: mg_chanacc_batch [YYYY-MM-DD] * Usage: mg_chanacc_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,8 +17,9 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_key[32]; char h_bizdate[16], h_key[32];
long h_amt = 0, total = 0, rows = 0; long h_cnt = 0, h_amt = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long tot_cnt = 0, tot_amt = 0, groups = 0;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,21 +27,21 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DECLARE bc CURSOR FOR EXEC SQL DECLARE cc CURSOR FOR
SELECT channel, coalesce(sum(amount),0) FROM mg_msg_log SELECT channel, count(*), coalesce(sum(amount),0) FROM mg_msg_log
WHERE biz_date = :h_bizdate GROUP BY channel; WHERE biz_date = :h_bizdate GROUP BY channel;
EXEC SQL OPEN bc; EXEC SQL OPEN cc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
for (;;) { for (;;) {
EXEC SQL FETCH bc INTO :h_key, :h_amt; EXEC SQL FETCH cc INTO :h_key, :h_cnt, :h_amt;
if (sqlca.sqlcode == 100) break; if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bc; tpabort(0); return 1; } if (sqlca.sqlcode < 0) { EXEC SQL CLOSE cc; tpabort(0); return 1; }
total += h_amt; rows++; tot_cnt += h_cnt; tot_amt += h_amt; groups++;
} }
EXEC SQL CLOSE bc; EXEC SQL CLOSE cc;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_chanacc_batch COMMIT: bizdate=%s groups=%ld total=%ld\n", bizdate, rows, total); printf(">>> mg_chanacc_batch COMMIT: bizdate=%s channels=%ld rows=%ld amount=%ld\n", bizdate, groups, tot_cnt, tot_amt);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_chansnap_batch.pgc - mg 모듈 커서 순회 후 대상 테이블 행별 INSERT 배치 (XA). * mg_chansnap_batch.pgc - mg 채널 last_stan 커서 갱신 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 커서 순회 후 대상 테이블 행별 INSERT; then tpcommit drives XA 2PC. * transaction; 채널별 최대 STAN 을 커서로 순회하며 mg_channel.last_stan 을
* 채널마다 행별 UPDATE 로 반영(스냅샷); then tpcommit drives XA 2PC.
* Usage: mg_chansnap_batch [YYYY-MM-DD] * Usage: mg_chansnap_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,8 +17,9 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_key[32]; char h_bizdate[16], h_key[32];
long h_amt = 0, rows = 0; long h_stan = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
long updated = 0;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,24 +27,23 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DECLARE bc CURSOR FOR EXEC SQL DECLARE nc CURSOR FOR
SELECT channel, coalesce(sum(amount),0) FROM mg_msg_log SELECT channel, coalesce(max(stan),0) FROM mg_msg_log
WHERE biz_date = :h_bizdate GROUP BY channel; WHERE biz_date = :h_bizdate GROUP BY channel;
EXEC SQL OPEN bc; EXEC SQL OPEN nc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
for (;;) { for (;;) {
EXEC SQL FETCH bc INTO :h_key, :h_amt; EXEC SQL FETCH nc INTO :h_key, :h_stan;
if (sqlca.sqlcode == 100) break; if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bc; tpabort(0); return 1; } if (sqlca.sqlcode < 0) { EXEC SQL CLOSE nc; tpabort(0); return 1; }
EXEC SQL INSERT INTO mg_chan_snap (channel, biz_date, amt) EXEC SQL UPDATE mg_channel SET last_stan = :h_stan WHERE channel = :h_key;
VALUES (:h_key, :h_bizdate, :h_amt); if (sqlca.sqlcode < 0) { EXEC SQL CLOSE nc; tpabort(0); return 1; }
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE bc; tpabort(0); return 1; } updated += sqlca.sqlerrd[2];
rows++;
} }
EXEC SQL CLOSE bc; EXEC SQL CLOSE nc;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_chansnap_batch COMMIT: bizdate=%s inserted=%ld\n", bizdate, rows); printf(">>> mg_chansnap_batch COMMIT: bizdate=%s updated=%ld\n", bizdate, updated);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_confirm_batch.pgc - mg 모듈 건수 확인 후 조건부 업데이트 배치 (XA). * mg_confirm_batch.pgc - mg 송신완료 큐 확인 전이 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 건수 확인 후 조건부 업데이트; then tpcommit drives XA 2PC. * transaction; 송신(S) 큐 존재 여부를 EXISTS(CASE) 로 판정하고, 존재할 때만
* 해당 큐를 확인완료(D) 로 UPDATE; then tpcommit drives XA 2PC.
* Usage: mg_confirm_batch [YYYY-MM-DD] * Usage: mg_confirm_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_cnt = 0, h_upd = 0; long h_flag = 0, h_upd = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,18 +26,19 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM mg_queue EXEC SQL SELECT CASE WHEN EXISTS
WHERE biz_date = :h_bizdate AND status = 'S'; (SELECT 1 FROM mg_queue WHERE biz_date = :h_bizdate AND status = 'S')
THEN 1 ELSE 0 END INTO :h_flag;
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } if (sqlca.sqlcode < 0) { tpabort(0); return 1; }
if (h_cnt > 0) { if (h_flag > 0) {
EXEC SQL UPDATE mg_queue SET status = 'C', updated_at = now() EXEC SQL UPDATE mg_queue SET status = 'D', updated_at = now()
WHERE biz_date = :h_bizdate AND status = 'S'; WHERE biz_date = :h_bizdate AND status = 'S';
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_confirm_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_confirm_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_upd = sqlca.sqlerrd[2]; h_upd = sqlca.sqlerrd[2];
} }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_confirm_batch COMMIT: bizdate=%s pending=%ld updated=%ld\n", bizdate, h_cnt, h_upd); printf(">>> mg_confirm_batch COMMIT: bizdate=%s has_sent=%ld confirmed=%ld\n", bizdate, h_flag, h_upd);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_dirstat_batch.pgc - mg 모듈 3분류 CASE 집계 배치 (XA). * mg_dirstat_batch.pgc - mg 수신/송신 금액 CASE 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 3분류 CASE 집계; then tpcommit drives XA 2PC. * transaction; 방향(IN/OUT)별 금액 합을 2개 CASE-sum 으로 집계하고, C 에서
* 순포지션(net=in-out)을 계산; then tpcommit drives XA 2PC.
* Usage: mg_dirstat_batch [YYYY-MM-DD] * Usage: mg_dirstat_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_a = 0, h_b = 0, h_c = 0; long h_in = 0, h_out = 0, h_net = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -26,14 +27,14 @@ int main(int argc, char **argv)
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT EXEC SQL SELECT
coalesce(sum(CASE WHEN direction = 'IN' THEN 1 ELSE 0 END),0), coalesce(sum(CASE WHEN direction = 'IN' THEN amount ELSE 0 END),0),
coalesce(sum(CASE WHEN direction = 'OUT' THEN 1 ELSE 0 END),0), coalesce(sum(CASE WHEN direction = 'OUT' THEN amount ELSE 0 END),0)
coalesce(sum(CASE WHEN direction = 'IN' THEN 1 ELSE 0 END),0) INTO :h_in, :h_out FROM mg_msg_log WHERE biz_date = :h_bizdate;
INTO :h_a, :h_b, :h_c FROM mg_msg_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_dirstat_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_dirstat_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_net = h_in - h_out;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_dirstat_batch COMMIT: bizdate=%s a=%ld b=%ld c=%ld\n", bizdate, h_a, h_b, h_c); printf(">>> mg_dirstat_batch COMMIT: bizdate=%s in=%ld out=%ld net=%ld\n", bizdate, h_in, h_out, h_net);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_distinct_batch.pgc - mg 모듈 고유값(distinct) 집계 배치 (XA). * mg_distinct_batch.pgc - mg 고유 채널/전문유형 수 집계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 고유값(distinct) 집계; then tpcommit drives XA 2PC. * transaction; 기준일 전문의 고유 채널 수와 고유 전문유형(mti) 수를 2개의
* count(DISTINCT ...) 로 동시에 집계; then tpcommit drives XA 2PC.
* Usage: mg_distinct_batch [YYYY-MM-DD] * Usage: mg_distinct_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_d = 0; long h_chan = 0, h_mti = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,11 +26,12 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(DISTINCT channel) INTO :h_d FROM mg_msg_log WHERE biz_date = :h_bizdate; EXEC SQL SELECT count(DISTINCT channel), count(DISTINCT mti)
INTO :h_chan, :h_mti FROM mg_msg_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_distinct_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_distinct_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_distinct_batch COMMIT: bizdate=%s distinct=%ld\n", bizdate, h_d); printf(">>> mg_distinct_batch COMMIT: bizdate=%s channels=%ld mtis=%ld\n", bizdate, h_chan, h_mti);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_errbps_batch.pgc - mg 모듈 두 SELECT 비율(bps) 산출 배치 (XA). * mg_errbps_batch.pgc - mg 실패 응답코드 비율(bps) 산출 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 두 SELECT 비율(bps) 산출; then tpcommit drives XA 2PC. * transaction; 단일 SELECT 에서 CASE-sum(rc<>'00') 으로 실패 건과 전체 건을
* 동시에 집계하고 C 에서 bps 를 계산; then tpcommit drives XA 2PC.
* Usage: mg_errbps_batch [YYYY-MM-DD] * Usage: mg_errbps_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_a = 0, h_b = 0, h_bps = 0; long h_fail = 0, h_tot = 0, h_bps = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,15 +26,14 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_a FROM mg_msg_log EXEC SQL SELECT
WHERE biz_date = :h_bizdate AND status = 'N'; coalesce(sum(CASE WHEN rc <> '00' THEN 1 ELSE 0 END),0), count(*)
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } INTO :h_fail, :h_tot FROM mg_msg_log WHERE biz_date = :h_bizdate;
EXEC SQL SELECT count(*) INTO :h_b FROM mg_msg_log WHERE biz_date = :h_bizdate; if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_errbps_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } h_bps = (h_tot > 0) ? h_fail * 10000 / h_tot : 0;
h_bps = (h_b > 0) ? h_a * 10000 / h_b : 0;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_errbps_batch COMMIT: bizdate=%s hit=%ld total=%ld bps=%ld\n", bizdate, h_a, h_b, h_bps); printf(">>> mg_errbps_batch COMMIT: bizdate=%s fail=%ld total=%ld bps=%ld\n", bizdate, h_fail, h_tot, h_bps);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_join_batch.pgc - mg 모듈 조인 집계 배치 (XA). * mg_join_batch.pgc - mg 큐 x 채널 조인 재시도 합계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 조인 집계; then tpcommit drives XA 2PC. * transaction; mg_queue 를 mg_channel 과 조인하여 UP 채널에 걸린 큐의 재시도
* 횟수 합계를 단일 집계로 산출; then tpcommit drives XA 2PC.
* Usage: mg_join_batch [YYYY-MM-DD] * Usage: mg_join_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_v = 0; long h_retry = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,13 +26,13 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(sum(a.amount),0) INTO :h_v EXEC SQL SELECT coalesce(sum(q.retry_cnt),0) INTO :h_retry
FROM mg_msg_log a JOIN mg_route b ON a.channel = b.channel FROM mg_queue q JOIN mg_channel c ON q.channel = c.channel
WHERE a.biz_date = :h_bizdate; WHERE q.biz_date = :h_bizdate AND c.status = 'UP';
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_join_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_join_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_join_batch COMMIT: bizdate=%s joined_sum=%ld\n", bizdate, h_v); printf(">>> mg_join_batch COMMIT: bizdate=%s retry_sum=%ld\n", bizdate, h_retry);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_marker_batch.pgc - mg 모듈 시퀀스 채번 + 마커 행 INSERT 배치 (XA). * mg_marker_batch.pgc - mg 일마감 마커 큐 적재 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 시퀀스 채번 + 마커 행 INSERT; then tpcommit drives XA 2PC. * transaction; 기준일 전문의 금액합/건수를 집계한 뒤, mg_queue 에 마감 마커
* 한 건을 nextval 채번으로 직접 INSERT(VALUES, 7컬럼); then tpcommit.
* Usage: mg_marker_batch [YYYY-MM-DD] * Usage: mg_marker_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +17,7 @@ int main(int argc, char **argv)
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19"; const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16]; char h_bizdate[16];
long h_id = 0, h_cnt = 0; long h_sum = 0, h_cnt = 0;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0; strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
@ -25,15 +26,15 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM mg_msg_log WHERE biz_date = :h_bizdate; EXEC SQL SELECT coalesce(sum(amount),0), count(*) INTO :h_sum, :h_cnt
FROM mg_msg_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } if (sqlca.sqlcode < 0) { tpabort(0); return 1; }
EXEC SQL SELECT nextval('mg_msg_seq') INTO :h_id; EXEC SQL INSERT INTO mg_queue (queue_id, stan, channel, mti, payload, status, biz_date)
if (sqlca.sqlcode < 0) { tpabort(0); return 1; } VALUES (nextval('mg_queue_seq'), 0, 'EOD', '0800', 'DAY MARK', 'Q', :h_bizdate);
EXEC SQL INSERT INTO mg_eod_mark (mark_id, biz_date, cnt) VALUES (:h_id, :h_bizdate, :h_cnt);
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_marker_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_marker_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_marker_batch COMMIT: bizdate=%s mark_id=%ld cnt=%ld\n", bizdate, h_id, h_cnt); printf(">>> mg_marker_batch COMMIT: bizdate=%s sum=%ld cnt=%ld\n", bizdate, h_sum, h_cnt);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_promote_batch.pgc - mg 모듈 상태 일괄 전이 업데이트 배치 (XA). * mg_promote_batch.pgc - mg 실패 큐 재시도 승격 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 상태 일괄 전이 업데이트; then tpcommit drives XA 2PC. * transaction; 실패(F) 큐를 대기(Q)로 되돌리면서 retry_cnt 를 산술 증가
* (SET retry_cnt = retry_cnt + 1) 시키는 UPDATE; then tpcommit drives XA 2PC.
* Usage: mg_promote_batch [YYYY-MM-DD] * Usage: mg_promote_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,13 +26,13 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL UPDATE mg_queue SET status = 'Q', updated_at = now() EXEC SQL UPDATE mg_queue SET retry_cnt = retry_cnt + 1, status = 'Q'
WHERE biz_date = :h_bizdate AND status = 'F'; WHERE biz_date = :h_bizdate AND status = 'F';
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_promote_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_promote_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_upd = sqlca.sqlerrd[2]; h_upd = sqlca.sqlerrd[2];
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_promote_batch COMMIT: bizdate=%s updated=%ld\n", bizdate, h_upd); printf(">>> mg_promote_batch COMMIT: bizdate=%s promoted=%ld\n", bizdate, h_upd);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_prunequeue_batch.pgc - mg 모듈 서브셀렉트 IN 조건 삭제 배치 (XA). * mg_prunequeue_batch.pgc - mg 비활성 채널 큐 정리 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 서브셀렉트 IN 조건 삭제; then tpcommit drives XA 2PC. * transaction; 기준일 큐 중 현재 UP 상태 채널 목록에 없는(NOT IN 서브셀렉트)
* 채널의 큐를 삭제; then tpcommit drives XA 2PC.
* Usage: mg_prunequeue_batch [YYYY-MM-DD] * Usage: mg_prunequeue_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -26,7 +27,8 @@ int main(int argc, char **argv)
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DELETE FROM mg_queue EXEC SQL DELETE FROM mg_queue
WHERE stan IN (SELECT stan FROM mg_msg_log WHERE biz_date = :h_bizdate AND status = 'N'); WHERE biz_date = :h_bizdate
AND channel NOT IN (SELECT channel FROM mg_channel WHERE status = 'UP');
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_prunequeue_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_prunequeue_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_del = sqlca.sqlerrd[2]; h_del = sqlca.sqlerrd[2];

View file

@ -1,8 +1,9 @@
/* /*
* mg_purge_batch.pgc - mg 모듈 상태 조건 삭제 배치 (XA). * mg_purge_batch.pgc - mg 종결 상태 큐 일괄 정리 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 상태 조건 삭제; then tpcommit drives XA 2PC. * transaction; 기준일 큐 중 종결 상태(송신 S / 완료 D / 확인 C)를 IN 값목록
* 으로 한 번에 삭제; then tpcommit drives XA 2PC.
* Usage: mg_purge_batch [YYYY-MM-DD] * Usage: mg_purge_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,7 +26,8 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DELETE FROM mg_queue WHERE biz_date = :h_bizdate AND status = 'S'; EXEC SQL DELETE FROM mg_queue
WHERE biz_date = :h_bizdate AND status IN ('S', 'D', 'C');
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_purge_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_purge_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_del = sqlca.sqlerrd[2]; h_del = sqlca.sqlerrd[2];

View file

@ -1,8 +1,9 @@
/* /*
* mg_rollup_batch.pgc - mg 모듈 INSERT ... SELECT 그룹 롤업 적재 배치 (XA). * mg_rollup_batch.pgc - mg 채널별 통계 조인 롤업 적재 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; INSERT ... SELECT 그룹 롤업 적재; then tpcommit drives XA 2PC. * transaction; mg_msg_log 를 mg_channel 과 조인하여 채널별 금액합을 GROUP BY
* 로 집계한 뒤 mg_stat 에 INSERT ... SELECT 로 적재; then tpcommit.
* Usage: mg_rollup_batch [YYYY-MM-DD] * Usage: mg_rollup_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,9 +26,11 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL INSERT INTO mg_chan_rollup (channel, biz_date, cnt, amt) EXEC SQL INSERT INTO mg_stat (channel, biz_date, in_cnt, out_cnt, err_cnt, amount_sum)
SELECT channel, biz_date, count(*), coalesce(sum(amount),0) SELECT m.channel, m.biz_date, 0, 0, 0, coalesce(sum(m.amount),0)
FROM mg_msg_log WHERE biz_date = :h_bizdate GROUP BY channel, biz_date; FROM mg_msg_log m JOIN mg_channel c ON m.channel = c.channel
WHERE m.biz_date = :h_bizdate
GROUP BY m.channel, m.biz_date;
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_rollup_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_rollup_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_rows = sqlca.sqlerrd[2]; h_rows = sqlca.sqlerrd[2];

View file

@ -1,8 +1,9 @@
/* /*
* mg_scalar_batch.pgc - mg 모듈 스칼라 합계 집계 배치 (XA). * mg_scalar_batch.pgc - mg 송신완료 출금 전문 금액 합계 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 스칼라 합계 집계; then tpcommit drives XA 2PC. * transaction; 기준일 전문 중 방향=OUT 이고 상태=S(송신완료)인 전문의 금액
* 합계를 단일 스칼라 집계(WHERE 3조건)로 산출; then tpcommit drives XA 2PC.
* Usage: mg_scalar_batch [YYYY-MM-DD] * Usage: mg_scalar_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -25,11 +26,12 @@ int main(int argc, char **argv)
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_v FROM mg_msg_log WHERE biz_date = :h_bizdate; EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_v FROM mg_msg_log
WHERE biz_date = :h_bizdate AND direction = 'OUT' AND status = 'S';
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_scalar_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_scalar_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; } if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> mg_scalar_batch COMMIT: bizdate=%s total=%ld\n", bizdate, h_v); printf(">>> mg_scalar_batch COMMIT: bizdate=%s out_sent_sum=%ld\n", bizdate, h_v);
tpclose(); tpterm(); tpclose(); tpterm();
return 0; return 0;

View file

@ -1,8 +1,9 @@
/* /*
* mg_spread_batch.pgc - mg 모듈 최대-최소 스프레드 집계 배치 (XA). * mg_spread_batch.pgc - mg 양수 금액 전문 최대-최소 스프레드 배치 (XA).
* *
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global * ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; 최대-최소 스프레드 집계; then tpcommit drives XA 2PC. * transaction; 기준일 전문 중 금액>0 인 건에 한해 max/min(2개 집계)을 뽑아
* C 에서 스프레드(max-min)를 계산; then tpcommit drives XA 2PC.
* Usage: mg_spread_batch [YYYY-MM-DD] * Usage: mg_spread_batch [YYYY-MM-DD]
*/ */
#include <stdio.h> #include <stdio.h>
@ -26,7 +27,8 @@ int main(int argc, char **argv)
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; } if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(max(amount),0), coalesce(min(amount),0) EXEC SQL SELECT coalesce(max(amount),0), coalesce(min(amount),0)
INTO :h_max, :h_min FROM mg_msg_log WHERE biz_date = :h_bizdate; INTO :h_max, :h_min FROM mg_msg_log
WHERE biz_date = :h_bizdate AND amount > 0;
if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_spread_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; } if (sqlca.sqlcode < 0) { fprintf(stderr, "mg_spread_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
h_spread = h_max - h_min; h_spread = h_max - h_min;

View file

@ -12,7 +12,10 @@ int mmdb_merch_status(const char *merch, char *status_out)
char h_merch[64], h_status[16]; char h_merch[64], h_status[16];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0; strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
EXEC SQL SELECT status INTO :h_status FROM mm_merchant_ext WHERE merchant_id = :h_merch; /* 확장 마스터 등급/상태를 함께 보고 유효 상태를 CASE 로 도출한다. */
EXEC SQL SELECT CASE WHEN status = 'ACTIVE' AND grade IN ('S','A','B','C')
THEN status ELSE 'HOLD' END
INTO :h_status FROM mm_merchant_ext WHERE merchant_id = :h_merch;
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) { userlog("mmdb_merch_status FAIL [%d]", sqlca.sqlcode); return -1; } if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) { userlog("mmdb_merch_status FAIL [%d]", sqlca.sqlcode); return -1; }
strncpy(status_out, h_status, 15); status_out[15] = 0; strncpy(status_out, h_status, 15); status_out[15] = 0;
return 0; return 0;

View file

@ -12,8 +12,10 @@ int vldb_merch_status(const char *merch, char *status_out)
char h_merch[64], h_status[16]; char h_merch[64], h_status[16];
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0; strncpy(h_merch, merch, sizeof(h_merch)-1); h_merch[sizeof(h_merch)-1] = 0;
EXEC SQL SELECT status INTO :h_status FROM merchant WHERE merchant_id = :h_merch; /* base merchant 원장에서 상태를 집계 조회(없으면 NONE)하여 항상 한 행을 얻는다. */
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) { userlog("vldb_merch_status FAIL [%d]", sqlca.sqlcode); return -1; } EXEC SQL SELECT coalesce(max(status), 'NONE') INTO :h_status
FROM merchant WHERE merchant_id = :h_merch;
if (sqlca.sqlcode < 0) { userlog("vldb_merch_status FAIL [%d]", sqlca.sqlcode); return -1; }
strncpy(status_out, h_status, 15); status_out[15] = 0; strncpy(status_out, h_status, 15); status_out[15] = 0;
return 0; return 0;
} }