고도화: 전 모듈 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,41 @@
/*
* vl_errgrp_batch.pgc - vl 반복 에러코드 그룹 집계 배치 (XA 단일 글로벌 트랜잭션 배치).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction, EXEC SQL runs on the biz_date, then tpcommit drives XA 2PC.
* Usage: vl_errgrp_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_errgrp_batch.h"
int main(int argc, char **argv)
{
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_min = 2, h_groups = 0;
EXEC SQL END DECLARE SECTION;
vl_errgrp_rec_t rec;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit 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; }
EXEC SQL SELECT count(*) INTO :h_groups FROM (
SELECT result_code FROM vl_check_log
WHERE biz_date = :h_bizdate AND result_code > 0
GROUP BY result_code HAVING count(*) >= :h_min) t;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_errgrp_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; }
rec.threshold = h_min; rec.groups = h_groups;
printf(">>> vl_errgrp_batch COMMIT: bizdate=%s 임계=%ld 반복에러그룹=%ld\n", bizdate, rec.threshold, rec.groups);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,40 @@
/*
* vl_logpurge_batch.pgc - vl 정상 검증로그 보존기간 삭제 배치 (XA 단일 글로벌 트랜잭션 배치).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction, EXEC SQL runs on the biz_date, then tpcommit drives XA 2PC.
* Usage: vl_logpurge_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_logpurge_batch.h"
int main(int argc, char **argv)
{
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
const char *cutoff = (argc > 2) ? argv[2] : VL_LOGPURGE_CUTOFF;
EXEC SQL BEGIN DECLARE SECTION;
char h_cut[16];
EXEC SQL END DECLARE SECTION;
vl_logpurge_rec_t rec;
(void) bizdate;
strncpy(h_cut, cutoff, sizeof(h_cut)-1); h_cut[sizeof(h_cut)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit 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; }
EXEC SQL DELETE FROM vl_check_log
WHERE biz_date < :h_cut AND result_code = 0;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_logpurge_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
rec.deleted = (long) sqlca.sqlerrd[2];
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_logpurge_batch COMMIT: cutoff=%s 삭제=%ld\n", cutoff, rec.deleted);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,40 @@
/*
* vl_orphan_batch.pgc - vl 고아 의심거래 점검 배치 (XA 단일 글로벌 트랜잭션 배치).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction, EXEC SQL runs on the biz_date, then tpcommit drives XA 2PC.
* Usage: vl_orphan_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_orphan_batch.h"
int main(int argc, char **argv)
{
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_orphans = 0;
EXEC SQL END DECLARE SECTION;
vl_orphan_rec_t rec;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit 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; }
EXEC SQL SELECT count(*) INTO :h_orphans FROM vl_suspect s
WHERE s.biz_date = :h_bizdate
AND NOT EXISTS (SELECT 1 FROM vl_check_log l WHERE l.target_id = s.purchase_id);
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_orphan_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
rec.orphans = h_orphans;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_orphan_batch COMMIT: bizdate=%s 고아의심=%ld\n", bizdate, rec.orphans);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,41 @@
/*
* vl_promote_batch.pgc - vl 실패 검증로그 의심거래 승격 배치 (XA 단일 글로벌 트랜잭션 배치).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction, EXEC SQL runs on the biz_date, then tpcommit drives XA 2PC.
* Usage: vl_promote_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_promote_batch.h"
int main(int argc, char **argv)
{
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
vl_promote_rec_t rec;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit 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; }
EXEC SQL INSERT INTO vl_suspect
(suspect_id, purchase_id, rule_code, severity, detail, biz_date)
SELECT nextval('vl_suspect_seq'), l.target_id, 'CHK_FAIL', 'WARN', l.detail, l.biz_date
FROM vl_check_log l
WHERE l.biz_date = :h_bizdate AND l.result_code > 0;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_promote_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
rec.promoted = (long) sqlca.sqlerrd[2];
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_promote_batch COMMIT: bizdate=%s 승격=%ld\n", bizdate, rec.promoted);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,49 @@
/*
* vl_rankscan_batch.pgc - vl 심각도별 최초 의심거래 랭크 스캔 배치 (XA 단일 글로벌 트랜잭션 배치).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction, EXEC SQL runs on the biz_date, then tpcommit drives XA 2PC.
* Usage: vl_rankscan_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_rankscan_batch.h"
int main(int argc, char **argv)
{
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_sid, h_rn;
EXEC SQL END DECLARE SECTION;
vl_rankscan_rec_t rec; rec.scanned = 0; rec.firsts = 0;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit 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; }
EXEC SQL DECLARE vrs CURSOR FOR
SELECT suspect_id,
ROW_NUMBER() OVER (PARTITION BY severity ORDER BY suspect_id)
FROM vl_suspect WHERE biz_date = :h_bizdate;
EXEC SQL OPEN vrs;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
for (;;) {
EXEC SQL FETCH vrs INTO :h_sid, :h_rn;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE vrs; tpabort(0); return 1; }
rec.scanned++;
if (h_rn == 1) rec.firsts++;
}
EXEC SQL CLOSE vrs;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_rankscan_batch COMMIT: bizdate=%s 스캔=%ld 최초=%ld\n", bizdate, rec.scanned, rec.firsts);
tpclose(); tpterm();
return 0;
}

View file

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

View file

@ -0,0 +1,22 @@
/*
* vl_corr_dbio.pgc - vl 모듈 DB 접근 함수 (vl_corr_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 규칙 기본심각도와 일치하는 의심거래 건수 (상관 서브쿼리).
*/
#include <string.h>
#include <userlog.h>
#include "vl_corr_dbio.h"
long vldb_rule_consistent(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 vl_suspect s
WHERE s.biz_date = :h_bizdate
AND s.severity = (SELECT r.severity FROM vl_rule r WHERE r.rule_code = s.rule_code);
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

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

View file

@ -0,0 +1,21 @@
/*
* vl_errdistinct_dbio.pgc - vl 모듈 DB 접근 함수 (vl_errdistinct_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 당일 의심거래에서 발화한 고유 규칙 수 (count DISTINCT).
*/
#include <string.h>
#include <userlog.h>
#include "vl_errdistinct_dbio.h"
long vldb_distinct_rules(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 rule_code) INTO :h_v
FROM vl_suspect WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { userlog("vldb_distinct_rules FAIL [%d]", sqlca.sqlcode); return -1; }
return h_v;
}

View file

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

View file

@ -0,0 +1,22 @@
/*
* vl_errfilter_dbio.pgc - vl 모듈 DB 접근 함수 (vl_errfilter_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 전체 대비 실패 검증 비율(bps) - FILTER 절 집계.
*/
#include <string.h>
#include <userlog.h>
#include "vl_errfilter_dbio.h"
long vldb_error_filter(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_err = 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 result_code > 0), count(*)
INTO :h_err, :h_tot FROM vl_check_log WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) return -1;
if (h_tot <= 0) return 0;
return h_err * 10000 / h_tot;
}

View file

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

View file

@ -0,0 +1,33 @@
/*
* vl_errgroup_dbio.pgc - vl 모듈 DB 접근 함수 (vl_errgroup_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 임계 이상 반복된 검증 에러코드 그룹 수 (GROUP BY HAVING 커서).
*/
#include <string.h>
#include <userlog.h>
#include "vl_errgroup_dbio.h"
/* 반복 임계(minc) 이상 발생한 에러코드(result_code) 그룹 수를 커서로 집계. */
long vldb_err_group_over(const char *bizdate, long minc)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_min, h_rc, 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 veg CURSOR FOR
SELECT result_code, count(*) FROM vl_check_log
WHERE biz_date = :h_bizdate AND result_code > 0
GROUP BY result_code HAVING count(*) >= :h_min;
EXEC SQL OPEN veg;
if (sqlca.sqlcode < 0) { userlog("vldb_err_group_over OPEN [%d]", sqlca.sqlcode); return -1; }
for (;;) {
EXEC SQL FETCH veg INTO :h_rc, :h_cnt;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE veg; return -1; }
groups++;
}
EXEC SQL CLOSE veg;
return groups;
}

View file

@ -0,0 +1,10 @@
/*
* vl_errgrp_batch.h - vl vl_errgrp_batch (copybook). vl
* + . Included by vl_errgrp_batch.pgc.
*/
#ifndef VL_ERRGRP_BATCH_H
#define VL_ERRGRP_BATCH_H
typedef struct { long threshold; long groups; } vl_errgrp_rec_t;
#endif /* VL_ERRGRP_BATCH_H */

View file

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

View file

@ -0,0 +1,22 @@
/*
* vl_errminmax_dbio.pgc - vl 모듈 DB 접근 함수 (vl_errminmax_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 당일 검증 에러코드 최대-최소 스프레드 (min/max).
*/
#include <string.h>
#include <userlog.h>
#include "vl_errminmax_dbio.h"
long vldb_err_spread(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_mn = 0, h_mx = 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(result_code),0), coalesce(max(result_code),0)
INTO :h_mn, :h_mx FROM vl_check_log
WHERE biz_date = :h_bizdate AND result_code > 0;
if (sqlca.sqlcode < 0) return -1;
return h_mx - h_mn;
}

View file

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

View file

@ -0,0 +1,22 @@
/*
* vl_inset_dbio.pgc - vl 모듈 DB 접근 함수 (vl_inset_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 미결 의심거래를 대상으로 남긴 검증로그 건수 (IN 서브셀렉트).
*/
#include <string.h>
#include <userlog.h>
#include "vl_inset_dbio.h"
long vldb_logged_targets(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 vl_check_log
WHERE biz_date = :h_bizdate
AND target_id IN (SELECT purchase_id FROM vl_suspect WHERE status = 'OPEN');
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

@ -0,0 +1,11 @@
/*
* vl_logpurge_batch.h - vl vl_logpurge_batch (copybook). vl
* + . Included by vl_logpurge_batch.pgc.
*/
#ifndef VL_LOGPURGE_BATCH_H
#define VL_LOGPURGE_BATCH_H
typedef struct { long deleted; } vl_logpurge_rec_t;
#define VL_LOGPURGE_CUTOFF "2026-07-01"
#endif /* VL_LOGPURGE_BATCH_H */

View file

@ -0,0 +1,10 @@
/*
* vl_orphan_batch.h - vl vl_orphan_batch (copybook). vl
* + . Included by vl_orphan_batch.pgc.
*/
#ifndef VL_ORPHAN_BATCH_H
#define VL_ORPHAN_BATCH_H
typedef struct { long orphans; } vl_orphan_rec_t;
#endif /* VL_ORPHAN_BATCH_H */

View file

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

View file

@ -0,0 +1,22 @@
/*
* vl_orphan_dbio.pgc - vl 모듈 DB 접근 함수 (vl_orphan_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 검증 로그가 없는 고아 의심거래 건수 (NOT EXISTS).
*/
#include <string.h>
#include <userlog.h>
#include "vl_orphan_dbio.h"
long vldb_orphan_suspect(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 vl_suspect s
WHERE s.biz_date = :h_bizdate
AND NOT EXISTS (SELECT 1 FROM vl_check_log l WHERE l.target_id = s.purchase_id);
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

@ -0,0 +1,10 @@
/*
* vl_promote_batch.h - vl vl_promote_batch (copybook). vl
* + . Included by vl_promote_batch.pgc.
*/
#ifndef VL_PROMOTE_BATCH_H
#define VL_PROMOTE_BATCH_H
typedef struct { long promoted; } vl_promote_rec_t;
#endif /* VL_PROMOTE_BATCH_H */

View file

@ -0,0 +1,11 @@
/*
* vl_promote_dbio.h - vl DB copybook (vl_promote_dbio). (result_code>0) (INSERT..SELECT).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef VL_PROMOTE_DBIO_H
#define VL_PROMOTE_DBIO_H
long vldb_promote_failed(const char *bizdate);
#endif /* VL_PROMOTE_DBIO_H */

View file

@ -0,0 +1,23 @@
/*
* vl_promote_dbio.pgc - vl 모듈 DB 접근 함수 (vl_promote_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 실패 검증로그(result_code>0)를 의심거래로 승격 (INSERT..SELECT).
*/
#include <string.h>
#include <userlog.h>
#include "vl_promote_dbio.h"
long vldb_promote_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 vl_suspect
(suspect_id, purchase_id, rule_code, severity, detail, biz_date)
SELECT nextval('vl_suspect_seq'), l.target_id, 'CHK_FAIL', 'WARN', l.detail, l.biz_date
FROM vl_check_log l
WHERE l.biz_date = :h_bizdate AND l.result_code > 0;
if (sqlca.sqlcode < 0) { userlog("vldb_promote_failed FAIL [%d]", sqlca.sqlcode); return -1; }
return (long) sqlca.sqlerrd[2];
}

View file

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

View file

@ -0,0 +1,20 @@
/*
* vl_purgelog_dbio.pgc - vl 모듈 DB 접근 함수 (vl_purgelog_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 기준일 이전 정상(result_code=0) 검증로그 삭제 후 삭제건수 반환 (DELETE 범위).
*/
#include <string.h>
#include <userlog.h>
#include "vl_purgelog_dbio.h"
long vldb_purge_checklog(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 vl_check_log
WHERE biz_date < :h_cut AND result_code = 0;
if (sqlca.sqlcode < 0) { userlog("vldb_purge_checklog FAIL [%d]", sqlca.sqlcode); return -1; }
return (long) sqlca.sqlerrd[2];
}

View file

@ -0,0 +1,11 @@
/*
* vl_rank_dbio.h - vl DB copybook (vl_rank_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 VL_RANK_DBIO_H
#define VL_RANK_DBIO_H
long vldb_rank_suspects(const char *bizdate);
#endif /* VL_RANK_DBIO_H */

View file

@ -0,0 +1,31 @@
/*
* vl_rank_dbio.pgc - vl 모듈 DB 접근 함수 (vl_rank_dbio), archived into libvldbio.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 "vl_rank_dbio.h"
long vldb_rank_suspects(const char *bizdate)
{
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_sid, h_rn, firsts = 0;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
EXEC SQL DECLARE vrk CURSOR FOR
SELECT suspect_id,
ROW_NUMBER() OVER (PARTITION BY severity ORDER BY suspect_id)
FROM vl_suspect WHERE biz_date = :h_bizdate;
EXEC SQL OPEN vrk;
if (sqlca.sqlcode < 0) return -1;
for (;;) {
EXEC SQL FETCH vrk INTO :h_sid, :h_rn;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE vrk; return -1; }
if (h_rn == 1) firsts++;
}
EXEC SQL CLOSE vrk;
return firsts;
}

View file

@ -0,0 +1,10 @@
/*
* vl_rankscan_batch.h - vl vl_rankscan_batch (copybook). vl
* + . Included by vl_rankscan_batch.pgc.
*/
#ifndef VL_RANKSCAN_BATCH_H
#define VL_RANKSCAN_BATCH_H
typedef struct { long scanned; long firsts; } vl_rankscan_rec_t;
#endif /* VL_RANKSCAN_BATCH_H */

View file

@ -0,0 +1,11 @@
/*
* vl_rulejoin_dbio.h - vl DB copybook (vl_rulejoin_dbio). (vl_suspect JOIN vl_rule).
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef VL_RULEJOIN_DBIO_H
#define VL_RULEJOIN_DBIO_H
long vldb_open_threshold_sum(const char *bizdate);
#endif /* VL_RULEJOIN_DBIO_H */

View file

@ -0,0 +1,22 @@
/*
* vl_rulejoin_dbio.pgc - vl 모듈 DB 접근 함수 (vl_rulejoin_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 미결 의심거래에 걸린 규칙 임계값 합 (vl_suspect JOIN vl_rule).
*/
#include <string.h>
#include <userlog.h>
#include "vl_rulejoin_dbio.h"
long vldb_open_threshold_sum(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(r.threshold),0) INTO :h_v
FROM vl_suspect s JOIN vl_rule r ON r.rule_code = s.rule_code
WHERE s.biz_date = :h_bizdate AND s.status = 'OPEN';
if (sqlca.sqlcode < 0) return -1;
return h_v;
}

View file

@ -0,0 +1,11 @@
/*
* vl_sevcase_dbio.h - vl DB copybook (vl_sevcase_dbio). (CRIT8/ERROR4/WARN2/1) - CASE .
* ECPG functions; run on the caller's XA branch (no EXEC SQL CONNECT).
* Return convention: >=0 ok, -1 = SQL error.
*/
#ifndef VL_SEVCASE_DBIO_H
#define VL_SEVCASE_DBIO_H
long vldb_severity_weighted(const char *bizdate);
#endif /* VL_SEVCASE_DBIO_H */

View file

@ -0,0 +1,25 @@
/*
* vl_sevcase_dbio.pgc - vl 모듈 DB 접근 함수 (vl_sevcase_dbio), archived into libvldbio.a.
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
* 심각도 가중합 (CRIT8/ERROR4/WARN2/그외1) - CASE 식.
*/
#include <string.h>
#include <userlog.h>
#include "vl_sevcase_dbio.h"
long vldb_severity_weighted(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 severity
WHEN 'CRIT' THEN 8
WHEN 'ERROR' THEN 4
WHEN 'WARN' THEN 2
ELSE 1 END), 0)
INTO :h_v FROM vl_suspect WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) return -1;
return h_v;
}