LOANSVC/i is a consumer-loan servicing application: loan origination and disbursement,
daily interest accrual with missed-due-date detection, weekly delinquency-fee assessment, and a
monthly charge-off plus portfolio valuation (WAC / ALLL) close. Every business rule lives in DB2 for i
SQL PL; the RPG programs orchestrate it through embedded EXEC SQL CALL. This manual is the
reference for the operator who runs the online screen and the periodic batch cycles, and for the
developer maintaining the application. It is grounded entirely in the committed source
(sqlpl-rpg-app/src/schema.sql, routines.sql, the five
*.rpgle.txt programs, LNINQDF.dds.txt, and the
test/ln_*.mjs drivers).
LOANSVC/i services the full life of a consumer instalment loan:
The application is deliberately split into two layers with a hard boundary:
routines.sql. This layer
also enforces integrity through triggers (non-negative balances, positive principal, audit).EXEC SQL CALL against the SQL-PL
procedures, checking SQLCODE after each call and DSPLYing the result. No loan math
is coded in RPG — the RPG never computes interest, applies a waterfall, or decides a
charge-off; it only drives the procedures that do.The benefit for operations: the rules are one auditable place (the SQL-PL routines), the same
procedures are reachable from RPG batch jobs, the interactive screen, and ad-hoc STRSQL alike, and the
RPG side stays trivial. Everything runs in library LOANSVC.
ORIGINATION ONLINE BATCH (periodic)
----------- ------ ----------------
LNAPPLY ---CALL---> LNINQPG (5250) LNDAILY ---> LN_ACCRUEDAILY -> LN_ACCRUEONE
LN_APPLY subfile over (accrual) LN_DUECHECK
LN_DISBURSE LNLOAN (A/D) LNWEEKLY ---> LN_WEEKLYFEES
opt 1 -> LN_POSTPAYMENT (fees)
opt 4 -> LN_INQUIRE LNMONTHLY ---> LN_CHARGEOFF
(close) LN_MONTHLYCLOSE
\ /
\ /
v v
LNCTL (control row: ASOFDATE, CLOSEYM) <-- operator sets before each batch run
|
v
LNLOAN <---writes--- every procedure triggers: TR_LOAN_BI/AI/AU/BU (LNLOAN)
| \ TR_LOANV_IOU (LNLOANV view)
| +--> LNTXN (one row per DISB/ACCR/PMT/LFEE/CHGO, seq from LNTXNSEQ)
| +--> LNAUD (trigger-written audit trail)
+------> LNCLOSE (monthly snapshot) LNWKLOG (weekly fee-run log)
A single processing event (say, a daily accrual) flows: operator sets LNCTL.ASOFDATE
→ submits LNDAILY → RPG reads the date and CALLs LN_ACCRUEDAILY
→ the procedure loops the portfolio, updating LNLOAN balances and inserting
LNTXN rows → triggers fire on those base-table changes (audit / integrity).
| Object | Type | Role |
|---|---|---|
| LNCUST | PF | Customer master. |
| LNRATETIER | PF | Credit-score rate/limit tiers. |
| LNLOAN | PF | Loan master (the heart of the app). |
| LNTXN | PF | Per-loan transaction journal. |
| LNAUD | PF | Trigger-written audit trail. |
| LNCLOSE | PF | Monthly portfolio valuation snapshot. |
| LNWKLOG | PF | Weekly fee-run log. |
| LNCTL | PF | One-row batch control table. |
| LNLOANV | View | LNLOAN⨯LNCUST join for maintenance. |
| LNTXNSEQ | Sequence | Transaction-sequence generator. |
| LN_* (8) | SQL functions | Date math, tier lookup, daily interest, delinquency bucket. |
| LN_* (12) | SQL procedures | Apply/disburse/accrue/due-check/pay/fees/charge-off/close/inquire/portfolio. |
| TR_* (5) | Triggers | Integrity, audit, view rerouting. |
| LNAPPLY | SQLRPGLE | Origination driver. |
| LNDAILY | SQLRPGLE | Daily cycle driver. |
| LNWEEKLY | SQLRPGLE | Weekly cycle driver. |
| LNMONTHLY | SQLRPGLE | Monthly cycle driver. |
| LNINQPG | SQLRPGLE | Interactive inquiry/maintenance program. |
| LNINQDF | DSPF (DDS) | Subfile display file for LNINQPG. |
The full object catalogue is 8 functions + 12 procedures + 5 triggers, over 8 PFs, 1 LF/view and 1 sequence, driven by 5 programs and 1 DDS member. Sections D and F expand each.
LOANSVC/i has no CICS transaction identifiers and no menu-driven transid switch. On IBM i,
each program is reached by name from a 5250 command-entry line (or a JOBQ/scheduler for the
batch jobs). The operator equivalent of "type a transid and Enter" is "type a CALL command
and Enter". Before invoking anything, the job's library list must include LOANSVC —
the tested jobs run with LIBL = QSYS QGPL LOANSVC QTEMP and CURLIB = LOANSVC.
| To do this | Type on the command line |
|---|---|
| Open the online inquiry/maintenance screen | CALL LOANSVC/LNINQPG |
| Originate + disburse (the packaged origination driver) | CALL LOANSVC/LNAPPLY |
| Run the daily cycle | CALL LOANSVC/LNDAILY (or SBMJOB it) |
| Run the weekly cycle | CALL LOANSVC/LNWEEKLY |
| Run the monthly cycle | CALL LOANSVC/LNMONTHLY |
| Set/inspect the batch control date (ad hoc SQL) | STRSQL → UPDATE LOANSVC/LNCTL ... |
The batch drivers take no CALL parameters — each reads its date from the LNCTL control
row (see section C), so a scheduled submission is a bare CALL. Only LNINQPG is interactive;
the four batch programs run to completion and DSPLY a one-line result per step.
LNINQPG is the one interactive program. It presents a subfile (DDS record SFLREC
under control record SFLCTLR, SFLPAG(10) per page, SFLSIZ(50))
listing every open loan (LSTAT IN ('A','D')), lets the operator key an option against any
row, processes the options, then reloads the subfile so the effect of a maintenance action is
visible immediately (real subfile-refresh discipline, not a static load-once list).
| Field | Type (DDS) | Shows |
|---|---|---|
| SOPT | 1A input/output | Option: 1=Post Payment, 4=Detail. |
| SLOANNO | 8A output | Loan number. |
| SCUSTNO | 6A output | Customer number. |
| SLSTAT | 1A output | Status: A active, D delinquent. |
| SPRINBAL | 11A output | Remaining principal (rendered from PRINBAL). |
| SACCRINT | 11A output | Accrued-unpaid interest. |
| SBUCKET | 10A output | Delinquency bucket from FN_DELQBUCKET(MISSEDCNT). |
| AMTIN | 9S,2 input | Payment amount on the control line, used with option 1. |
1 against a loan row and type the amount in
Amt, then Enter. LNINQPG reads ASOFDATE from LNCTL and
calls LN_POSTPAYMENT(loan, amount, asof). The payment applies fees→interest→principal;
delinquency resets (MISSEDCNT=0), the due date rolls +30d; a full-balance payment marks
the loan paid off (LSTAT='F'). Result is DSPLYed (APPLIED/REJECTED
+ SQLCODE) and the subfile reloads.4, Enter. Calls
LN_INQUIRE and DSPLYs the loan's customer, status and balances.CA03/CA12; the program exits on either).EXEC SQL VALUES FN_DELQBUCKET(:missedcnt) INTO
:bucket. The keyed payment amount is copied out of the DDS numeric field into a plain host
variable before it is passed to LN_POSTPAYMENT. These are engine-compatibility
accommodations documented in the program source; operationally the screen behaves as described.Honest statement: LOANSVC/i does not model a true four-eyes maker–checker /
separate-authorization workflow. There is no "one user posts, a second user approves" step in the code:
a payment posted through LNINQPG option 1 is applied immediately by LN_POSTPAYMENT, and an
origination through LNAPPLY approves-and-disburses in one flow. The manual documents the control model
the application does have:
TR_LOAN_AI writes an APPLY row on each new loan (customer, principal,
status); TR_LOAN_AU writes a STATUS row only when LSTAT actually
changes (WHEN clause), e.g. P->A at disbursement or A->D on a missed
due date. This is the after-the-fact accountability trail, not an approval gate.LN_DISBURSE
rejects a loan not in PENDING (SQLSTATE 76101); LN_POSTPAYMENT rejects a payment
against a loan not active/delinquent (76103) and a non-positive amount (76102).TR_LOAN_BI vetoes non-positive principal (76201);
TR_LOAN_BU vetoes any balance going negative (76202).TR_LOANV_IOU (INSTEAD OF UPDATE on LNLOANV)
rejects any attempt to edit balances through the maintenance view (76203) — balances
may change only through LN_POSTPAYMENT. It does allow a servicer to override a
loan's LSTAT through the view, rerouting that change to the base table (which then trips
the TR_LOAN_AU audit).In sum, the control posture is audit + status/state gating + integrity enforcement, all enforced in the data layer, rather than a segregation-of-duties approval workflow.
LOANSVC/i's servicing runs as periodic cycles rather than one monolithic nightly job: a daily
cycle (accrual + due-check), a weekly cycle (delinquency fees), and a monthly cycle
(charge-off + close). All three batch programs take no CALL parameters; each reads its processing
date — and, for the monthly job, the close year-month — from the single-row LNCTL
control table. This is the SBMJOB idiom: a scheduled/JOBQ submission sets the date on the control row,
then simply calls the program with no parms.
-- CTL maintenance: set the processing date the next cycle runs for UPDATE LOANSVC/LNCTL SET ASOFDATE = 20260805 WHERE CTLKEY = 'X'; -- for the monthly job, also set the close month (YYYYMM) UPDATE LOANSVC/LNCTL SET ASOFDATE = 20260901, CLOSEYM = 202609 WHERE CTLKEY = 'X'; -- then submit the (parameterless) cycle SBMJOB CMD(CALL PGM(LOANSVC/LNDAILY)) JOB(LNDAILY)
| Program | Purpose | Procedures / functions called | Inputs | Outputs | Frequency |
|---|---|---|---|---|---|
| LNAPPLY | Originate & (if approved) disburse a loan. | LN_APPLY then LN_DISBURSE; indirectly FN_RATETIER/FN_MAXPRIN/FN_ADDDAYS. |
Host-variable applications coded in the driver (custno, principal, term, appdate). | DSPLY per application (APPn=loanno/status/sqlcode, DISBn=sqlcode); LNLOAN + LNTXN(DISB) + LNAUD rows. |
Ad hoc / on demand. |
| LNDAILY | Accrue daily interest, then detect missed due dates. | LN_ACCRUEDAILY (→ LN_ACCRUEONE → FN_DAILYINT/FN_ADDDAYS), LN_DUECHECK. |
LNCTL.ASOFDATE. |
DSPLY ASOF=, ACCR=nloans/totaccr/sqlcode, DUECHK=nmissed/sqlcode; ACCR txns; loans flip to D. |
Daily. |
| LNWEEKLY | Assess delinquency late fees. | LN_WEEKLYFEES. |
LNCTL.ASOFDATE (used as week-ending date). |
DSPLY WKFEES=nfeed/totfees/sqlcode; LFEE txns; LNWKLOG row; FEEBAL increased. |
Weekly. |
| LNMONTHLY | Charge off 3+cycle delinquents, then close/value the portfolio. | LN_CHARGEOFF, LN_MONTHLYCLOSE. |
LNCTL.ASOFDATE and LNCTL.CLOSEYM. |
DSPLY CHGOFF=nchgoff/totloss/sqlcode, CLOSE=closeym/sqlcode; CHGO txns; LNCLOSE row. |
Monthly (month-end). |
Reads ASOFDATE from LNCTL, then: (1) LN_ACCRUEDAILY(asof) accrues simple
daily interest on every A/D loan from each loan's LASTACCRDT+1 through the as-of date
inclusive — a loan that missed processing days catches all of them up in one call, posting one ACCR
txn and advancing LASTACCRDT; (2) LN_DUECHECK(asof) bumps MISSEDCNT,
rolls NEXTDUEDT +30d and flips to DELINQUENT any A/D loan whose NEXTDUEDT < asof.
Expected DSPLY (day-4 accrual on one 5000.00 @8% loan): ASOF=20260805/0 ACCR=1/4.40/0 1 loan, 4 days x 1.10 = 4.40, SQLCODE 0 DUECHK=0/0 no missed loans yet
Reads the week-ending date from LNCTL.ASOFDATE and calls
LN_WEEKLYFEES(wkenddt): for each DELINQUENT loan it adds
$25.00 × MISSEDCNT to FEEBAL, posts an LFEE txn, and writes one LNWKLOG
row for the week. Active loans are never fee'd.
Expected DSPLY (1 delinquent loan, MISSEDCNT=1): WKFEES=1/25.00/0 1 loan fee'd, $25.00 total, SQLCODE 0
WKENDDT; LNWKLOG's primary key on
WKENDDT blocks a duplicate and is your guard.Reads ASOFDATE and CLOSEYM, then: (1) LN_CHARGEOFF(asof) writes
off every delinquent loan with MISSEDCNT ≥ 3 — loss = PRINBAL+ACCRINT+FEEBAL,
posts a CHGO txn, sets LSTAT='X' and zeroes balances; (2) LN_MONTHLYCLOSE(closeym)
snapshots the portfolio into LNCLOSE: A/D counts, total principal & accrued interest, the
principal-weighted average coupon (WAC_BP), and the ALLL reserve (2% of active PRINBAL + 25%
of delinquent PRINBAL — a deliberately simple, auditable figure, not a regulatory model). One row
per month via DELETE-then-INSERT.
Expected DSPLY (one 3+cycle loan charged off, then close): CHGOFF=1/2083.00/0 1 loan written off, 2083.00 loss CLOSE=202609/0 valuation snapshot written for 202609
LN_DUECHECK flips loans to DELINQUENT and
increments MISSEDCNT; weekly fees are $25 × MISSEDCNT, so daily must
run first or fees are under-assessed.MISSEDCNT ≥ 3 (built up by daily due-checks), and the valuation must be computed on
fully accrued, fully fee'd balances. Run the month's dailies and weeklies, then the monthly close
last.All files are in library LOANSVC, grounded in schema.sql. Dates are stored
as INT in YYYYMMDD form (or YYYYMM for close month); rates are
INT basis points (500 = 5.00%); money is DECIMAL.
| Field | Type | Meaning |
|---|---|---|
| CUSTNO | CHAR(6) | Customer number (PK). |
| CNAME | VARCHAR(40) | Customer name. |
| CSTAT | CHAR(1) | A active, H hold (no new loans), C closed. |
| CSCORE | SMALLINT | Credit score 300–850 (drives the rate tier). |
| Field | Type | Meaning |
|---|---|---|
| TIERNO | SMALLINT | Tier number (PK). |
| MINSCORE | SMALLINT | Lowest score (inclusive) this tier covers; the highest floor ≤ a score wins. |
| RATEBP | INT | Annual rate in basis points. |
| MAXPRIN | DECIMAL(11,2) | Max principal approvable at this tier. |
Tested tier set: 300→1800bp/2000, 580→1200bp/10000, 680→800bp/25000, 750→500bp/50000.
| Field | Type | Meaning |
|---|---|---|
| LOANNO | CHAR(8) | Loan number (PK), e.g. LN000001. |
| CUSTNO | CHAR(6) | Owning customer (FK). |
| PRINCIPAL | DECIMAL(11,2) | Original principal. |
| RATEBP | INT | Annual rate, basis points (from the score tier). |
| TERMMOS | SMALLINT | Term in months (informational). |
| APPDATE / STARTDATE | INT | Applied date / disbursed date (YYYYMMDD). |
| LSTAT | CHAR(1) | P pending, A active, D delinquent, F paid-off, X charged-off, R rejected. |
| PRINBAL | DECIMAL(11,2) | Remaining principal. |
| ACCRINT | DECIMAL(11,2) | Accrued-unpaid interest bucket. |
| FEEBAL | DECIMAL(11,2) | Accrued-unpaid late fees. |
| LASTACCRDT | INT | Interest last accrued through (accrual basis). |
| NEXTDUEDT | INT | Next scheduled payment due date. |
| DUEDAY | SMALLINT | Day-of-month due (1–28). |
| MISSEDCNT | SMALLINT | Consecutive missed due dates (drives fees & charge-off). |
| PAIDOFFDT / CHGOFFDT | INT | Paid-off / charged-off dates when applicable. |
| Field | Type | Meaning |
|---|---|---|
| LOANNO / TXNSEQ | CHAR(8) / INT | Loan + sequence number (from LNTXNSEQ) (PK). |
| TXNDATE | INT | Transaction date (YYYYMMDD). |
| TXNTYPE | CHAR(4) | DISB disbursement, ACCR accrual, PMT payment, LFEE late fee, CHGO charge-off. |
| AMT | DECIMAL(11,2) | Signed amount of what the txn represents. |
| PRINBAL | DECIMAL(11,2) | Principal balance snapshot AFTER this txn. |
| MEMO | VARCHAR(40) | Free-text detail (e.g. the payment waterfall split). |
| Field | Type | Meaning |
|---|---|---|
| AUDSEQ | INT identity | Generated-always audit sequence (PK). |
| AUDTS | TIMESTAMP | When (default CURRENT TIMESTAMP). |
| LOANNO | CHAR(8) | Loan affected. |
| OP | VARCHAR(10) | APPLY (insert) or STATUS (LSTAT change). |
| DETAIL | VARCHAR(80) | Human-readable detail written by the trigger. |
| Field | Type | Meaning |
|---|---|---|
| CLOSEYM | INT | Close year-month YYYYMM (PK). |
| NUMACTIVE / NUMDELINQ | INT | Active / delinquent loan counts. |
| TOTPRINBAL | DECIMAL(13,2) | Total principal over open loans. |
| TOTACCRINT | DECIMAL(13,2) | Total accrued interest over open loans. |
| WAC_BP | DECIMAL(9,2) | Principal-weighted average coupon, basis points. |
| ALLLRESERVE | DECIMAL(13,2) | Loss-reserve estimate. |
| CLOSEDTS | TIMESTAMP | When the close ran. |
| Field | Type | Meaning |
|---|---|---|
| WKENDDT | INT | Week-ending date (PK) — the duplicate-run guard. |
| NUMFEED | INT | Loans fee'd that week. |
| TOTFEES | DECIMAL(11,2) | Total fees assessed that week. |
| Field | Type | Meaning |
|---|---|---|
| CTLKEY | CHAR(1) | Always 'X' (PK, single row). |
| ASOFDATE | INT | Processing/as-of date read by every batch program. |
| CLOSEYM | INT | Close year-month read by the monthly program. |
Seeded row: ('X', 20260801, 202608). Operators advance it before each cycle.
Join view exposing LOANNO, CUSTNO, CNAME, PRINCIPAL, RATEBP, TERMMOS, LSTAT, PRINBAL, ACCRINT,
FEEBAL, NEXTDUEDT, MISSEDCNT. Updatable only through TR_LOANV_IOU (INSTEAD OF UPDATE):
balance edits are rejected (76203); an LSTAT override reroutes to the base table.
CREATE SEQUENCE LOANSVC/LNTXNSEQ AS INT START WITH 1 NO CYCLE — the global generator
every procedure draws TXNSEQ from via NEXT VALUE FOR, so all LNTXN rows share one
monotonic sequence.
UPDATE LOANSVC/LNCTL SET ASOFDATE = <YYYYMMDD> WHERE CTLKEY='X'.SBMJOB CMD(CALL PGM(LOANSVC/LNDAILY)).LNWEEKLY (same ASOFDATE = week-ending date), then check the WKFEES= line and the new LNWKLOG row.CALL LOANSVC/LNINQPG (option 1) as they arrive.CALL LOANSVC/LNAPPLY (or the procedures directly).Pre-checks: confirm LNCTL holds the intended date; confirm the job's library list
includes LOANSVC.
Post-checks after the daily cycle:
ASOF= matches the date you set; both CALL lines end in /0 (SQLCODE 0).ACCR= loan count & total reconcile to the open portfolio; exactly one ACCR txn per loan per run.DUECHK= equals the loans whose NEXTDUEDT passed; those are now LSTAT='D' with MISSEDCNT bumped and NEXTDUEDT rolled +30d.UPDATE LOANSVC/LNCTL SET ASOFDATE = <month-end>, CLOSEYM = <YYYYMM> WHERE CTLKEY='X'.LNMONTHLY. Confirm CHGOFF= and CLOSE=<YYYYMM>/0.SELECT NUMACTIVE, NUMDELINQ, TOTPRINBAL, TOTACCRINT, WAC_BP, ALLLRESERVE FROM LOANSVC/LNCLOSE WHERE CLOSEYM = <YYYYMM>;
Reconciling figures (the same ones the volume simulation checks against an independent JS oracle):
TOTPRINBAL = SUM(PRINBAL) over open (A+D) loans; TOTACCRINT = SUM(ACCRINT) over the same set.CHGOFF= count/loss equal the loans that were D with MISSEDCNT≥3; those are now X, zero-balance, with a CHGO txn each.WAC_BP = Σ(PRINBAL×RATEBP)/TOTPRINBAL, e.g. (5000×800 + 3000×1200)/8000 = 950.00 bp.ALLLRESERVE = 2% of active PRINBAL + 25% of delinquent PRINBAL, e.g. 100.00 + 750.00 = 850.00.Ad-hoc portfolio listing: CALL LOANSVC/LN_PORTFOLIO() returns one row per open loan
(loan, customer, status, balances, missed count, delinquency bucket) for a report or STRSQL review.
Each RPG driver DSPLYs its result with the trailing SQLCODE. A healthy run ends every line
in /0; a negative trailing value means the EXEC SQL CALL failed with a specific
SQLSTATE (section F.5).
| Situation | Behaviour | Action |
|---|---|---|
| Daily cycle fails partway | Un-accrued loans keep their old LASTACCRDT. | Re-submit LNDAILY for the same ASOFDATE: already-accrued loans are a no-op, the rest catch up. Idempotent off the control row. |
| Re-run same day's accrual | Accrues 0 additional days (LASTACCRDT+1 > ASOF). | Safe no-op. Only advance ASOFDATE to process a new day. |
| Monthly close fails | No partial LNCLOSE row (INSERT is the last step). | Fix data and re-submit; DELETE-then-INSERT replaces the month cleanly (idempotent per month). |
| Charge-off re-run | Charged-off loan is X, no longer matches D&MISSEDCNT≥3. | Naturally idempotent for a fixed portfolio — never charged off twice. |
| Weekly fees re-run same week | Not idempotent by design. | Do not resubmit the same WKENDDT; LNWKLOG PK blocks a duplicate. |
| SQLSTATE 76204 on accrual | A loan reached A/D with NULL LASTACCRDT (never properly disbursed). | Disburse it via LN_DISBURSE or move it out of A/D scope, then re-run. The guard prevents an infinite accrual loop. |
| Rejected payment | LN_POSTPAYMENT traps the exception, sets result REJECTED and RESIGNALs. | Non-zero SQLCODE surfaces to the caller; balances are left unchanged. Correct the input and retry. |
The complete SQL-PL surface, from routines.sql. All objects are in library
LOANSVC.
YYYYMMDD as ISO YYYY-MM-DD (so DATE() can parse it).RATEBP of the highest score-floor tier ≤ the score (correlated subquery on LNRATETIER).MAXPRIN of that same tier — the underwriting ceiling.ROUND(PRINBAL × (RATEBP/100/100) / 365, 2), 365-day convention.LNnnnnnn.The RPG programs use these embedded-SQL idioms against the SQL-PL layer:
exec sql select ASOFDATE into :asof from LOANSVC.LNCTL where CTLKEY='X';exec sql call LOANSVC.LN_ACCRUEDAILY(:asof, :nloans, :totaccr); then check SQLCODE.dow sqlcode = 0.exec sql values FN_DELQBUCKET(:missedcnt) into :bucket;%char(sqlcode)
after each call; the SQL-PL procedures raise application SQLSTATEs (below) via SIGNAL/RESIGNAL, and
LN_POSTPAYMENT captures the message with GET DIAGNOSTICS.| SQLSTATE | Raised by | Meaning |
|---|---|---|
| 76100 | LN_APPLY / LN_DISBURSE / LN_POSTPAYMENT / LN_INQUIRE | Customer or loan not found (NOT FOUND handler). |
| 76101 | LN_DISBURSE | Loan is not in PENDING status. |
| 76102 | LN_POSTPAYMENT | Payment amount must be positive. |
| 76103 | LN_POSTPAYMENT | Loan is not active or delinquent. |
| 76201 | TR_LOAN_BI | Principal must be positive. |
| 76202 | TR_LOAN_BU | A loan balance cannot go negative. |
| 76203 | TR_LOANV_IOU | Balances must change via LN_POSTPAYMENT, not the view. |
| 76204 | LN_ACCRUEONE | Loan has no LASTACCRDT — must be disbursed via LN_DISBURSE before accrual. |
SBMJOB CMD(CALL PGM(LOANSVC/LNDAILY))).EXEC SQL CALL and reading data with SELECT INTO / cursors.