This document discusses using DB2 external stored procedures on IBM i to load data from delimited files into database tables in parallel. It provides an example stored procedure program that submits Copy from Import File commands to batch processing to load multiple tables simultaneously. Calling the stored procedure from a client allows loading data faster without locking the GUI interface for an extended time.
1. DB2 for i External Stored Procedure Example
Rational for i and Optim Studio Development Environment ............................................. 1
Load Process Flowchart (ACS_i5Load and ACSGenesis)................................................ 2
Run Stored Procedure from Optim and Rational for i packages (client)............................ 3
CPYFRMIMPF commands are submitted for batch processing on i ................................. 3
Module syb_i5_LoadFromDelimitedFile in service program ACSGENESIS ................... 4
DB2 External Stored Procedure Interface........................................................................... 6
DB2 External Stored Procedure Program ........................................................................... 7
Benefits of Stored Procedure Processing versus ODBC/JDBC statements........................ 8
Two Types of Stored Procedures .................................................................................... 8
Maintenance performed in one place.............................................................................. 8
Get Job Completion Status of Stored Procedure with a Select Statement.......................... 9
References......................................................................................................................... 10
Rational for i and Optim Studio Development Environment
• We would like to load many tables as fast as possible without locking our GUI for
an extended timeframe.
Page 1 of 10
1/3/2011 4:49:44 PM
2. DB2 for i External Stored Procedure Example
Load Process Flowchart (ACS_i5Load and ACSGenesis)
Page 2 of 10
1/3/2011 4:49:44 PM
3. DB2 for i External Stored Procedure Example
Run Stored Procedure from Optim and Rational for i packages (client)
CPYFRMIMPF commands are submitted for batch processing on i
Page 3 of 10
1/3/2011 4:49:44 PM
4. DB2 for i External Stored Procedure Example
Module syb_i5_LoadFromDelimitedFile in service program ACSGENESIS
// * ============================================================== *
// * DB2 for i: Load from delimited files (syB) to ACS tables (db2) *
// * ============================================================== *
p syb_i5_LoadFromDelimitedFile...
p b export
d syb_i5_LoadFromDelimitedFile...
d pi n
d i5_Context 32 const
d i5_Working 128 const
d i5_Schema 128 const
d i5_BegPos s 5u 0 inz(0)
d i5_EndPos s 5u 0 inz(0)
d i5_LibFil s 20 inz(' ')
d i5_CpyFil s 1024 inz(' ')
d exist s 1 inz('0')
d existIndicator s n based(sqlPointer)
d sqlPointer s * inz(%ADDR(exist))
d i5_LibNme s 10 inz(' ')
/Free
Monitor;
// * ============================================================== *
// * Check / Set import application context and working directories *
// * ============================================================== *
If isApplicationWorkingDirectoryValid( %trim(i5_Context):
%trim(i5_Working) );
i5_dirName = %trim(i5_Context) + '/' + %trim(i5_Working);
If i5_Schema = 'QUSER';
i5_LibNme = RtvCurLib( pgmStatus.jobName:
pgmStatus.userId:
pgmStatus.jobNumber );
Else;
i5_LibNme = pgmStatus.userId;
EndIf;
i5_dirPtr = OpenDir(%trim(i5_dirName));
If (i5_dirPtr <>*NULL);
DoU i5_dirEntPtr = *Null;
i5_dirEntPtr = ReadDir( i5_dirPtr );
Monitor;
On-Error *All;
EndMon;
If i5_dirEntPtr = *Null;
Leave;
Else;
i5_entryName = %str(%addr(i5_nameFull));
// * ============================================================== *
// * Filter navigation entries (.) and select .data delimited files *
// * ============================================================== *
If %subst(i5_entryName: 1: 1) <> '.';
i5_EndPos = %scan('.data':
%xlate(upper: lower: %trim(i5_entryName)): 1);
If i5_EndPos <> 0;
i5_BegPos = %scan('.': %xlate(upper: lower:
%subst(%trim(i5_entryName): 1: i5_EndPos - 1)): 1);
Page 4 of 10
1/3/2011 4:49:44 PM
6. DB2 for i External Stored Procedure Example
i5_JobNbr = %subst(messageInfo.errMsgDta: 21: 6);
i5_UsrDta = %subst(%trim(i5_entryName)
:(i5_BegPos + 1)
:((i5_EndPos - i5_BegPos) - 1));
If Not WrtLogSts('ACSLOAD_01': i5_TskCnt: i5_JobNme:
i5_UsrNme: i5_JobNbr: i5_UsrDta);
// Add additional error handling logic here ======>
EndIf;
EndIf;
Else;
// Add additional error handling logic here ======>
EndIf;
EndIf;
EndIf;
Else;
snd_Data = 'LOAD WARNING: ' + %trim(i5_entryName) +
' in ' + %trim(pgmStatus.mainProcName);
EndIf;
CallP(e) sndjobmsg(snd_Data); // Job Log Message Entry
EndIf;
EndIf;
EndDo;
existIndicator = *ON; // Return SUCCESS code
Else;
i5_errNoPtr = errno();
snd_Data = 'Open directory failed from ' + %trim(i5_dirName) +
' in program ' + %trim(pgmStatus.mainProcName);
CallP(e) sndjobmsg(snd_Data); // Job Log Message Entry
EndIf;
closeDir(i5_dirPtr);
EndIf;
On-Error *All;
snd_Data = 'Unexpected error in syb_i5_loadFromDelimitedFile()' +
' in program ' + %trim(pgmStatus.mainProcName);
CallP(e) sndjobmsg(snd_Data); // Job Log Message Entry
EndMon;
Return existIndicator;
/End-Free
p syb_i5_LoadFromDelimitedFile...
p e
DB2 External Stored Procedure Interface
Create Procedure i5ParallelDataLoader (
IN Type char( 10) )
LANGUAGE RPGLE
SPECIFIC ACS_I5LOAD
NOT DETERMINISTIC
External Name ACS_I5LOAD
CALLED ON NULL INPUT
PARAMETER STYLE DB2SQL;
Page 6 of 10
1/3/2011 4:49:44 PM
7. DB2 for i External Stored Procedure Example
DB2 External Stored Procedure Program
* ================================================================== *
* Program name...: ACS_i5LOAD *
* Purpose........: Load database tables from delimited files *
* Programmer.....: Thomas and Victoria Wolfe *
* Create Date....: December 7, 2010 *
* *
* Maintenance Log: *
* *
* PGMR SEARCH DATE DESC. OF CHANGE *
* *
* ================================================================== *
/COPY qCPYSRC,ACS_H_PGM
/COPY QPRTSRC,ACSGENESIS
d i5_LoadType s 10
d i5_NullInd1 s 5i 0
d sqlStateCode s 5
d functionName s 517
d specificName s 128
d errorMessage s 70
d i5_ProdLoad s 10 inz(' ')
d message s 80 inz(*Blank)
d command s 2048 inz(' ')
* ================================================================== *
* Common program status information data structure (SDS) *
* ================================================================== *
/COPY QCPYSRC,ACS_SQLOPT
* ================================================================== *
* i5 DB2 Parallel Data Loader: Submit CpyFrmImpF command to batch *
* ================================================================== *
c *entry plist
c parm i5_LoadType
c parm i5_NullInd1
c parm sqlStateCode
c parm functionName
c parm specificName
c parm errorMessage
/Free
Monitor; // Global error handler
sqlStateCode = '00000';
If i5_NullInd1 = 0;
i5_ProdLoad = i5_LoadType;
Select;
When %xlate(upper: lower: %trim(i5_ProdLoad)) = '*sybase';
If syb_i5_LoadFromDelimitedFile(%trim(syB_Context):
Page 7 of 10
1/3/2011 4:49:44 PM
8. DB2 for i External Stored Procedure Example
%trim(syB_dataDump):
%trim(pgmStatus.UserId) );
Else;
sqlStateCode = '38999';
errorMessage = 'Error occured in external stored ' +
'procedure. Contact support and report ' +
'this error message.';
EndIf;
Other;
sqlStateCode = '38001';
errorMessage = 'Invalid input load parameter ' +
%trim(i5_ProdLoad) + ' not processed.';
EndSL;
Else;
sqlStateCode = '38001';
errorMessage = 'Null input load parameter not' +
' processed.';
EndIf;
On-Error *All; // Unmonitored Errors?
Dump(a);
EndMon;
*inlr = *On;
Return;
/End-Free
Benefits of Stored Procedure Processing versus ODBC/JDBC statements
• Secure access to DB2 data.
• Access non-DB2 data if necessary –VSAM, IMS, etc.
• Code business logic once
o Maintenance is simpler
• Performance improvement?
o Instead of multiple SQL statements being sent
• Lots of languages to choose from
Two Types of Stored Procedures
• SQL Stored Procedures
• External Procedures
Maintenance performed in one place
Page 8 of 10
1/3/2011 4:49:44 PM
9. DB2 for i External Stored Procedure Example
Get Job Completion Status of Stored Procedure with a Select Statement
Select PROCESS,
PRCSEQ,
Cast(Case
When STATUS = 'N'
Then 'Success'
When STATUS = ‘A’
Then ‘Failure’
Else 'Running’
End As Character(7)) As Status,
STARTSTMP,
ENDSTMP,
RUNNAME,
RUNUSER,
RUNNUMBER,
ERRORID,
USRDATA
From ACSJOBLOG
Order by 4,1,2
Page 9 of 10
1/3/2011 4:49:44 PM
10. DB2 for i External Stored Procedure Example
References
Writing Stored Procedures in RPG MC Press Online 15 January 2008, Susan Gantner
http://www.mcpressonline.com/programming/rpg/writing-stored-procedures-in-rpg.html
Stored Procedures, Triggers, and User-Defined Functions on DB2 UDB for iSeries
http://www.redbooks.ibm.com/abstracts/sg246503.html
DB2 UDB for AS/400 Object Relational Support
http://www.redbooks.ibm.com/abstracts/sg245409.html
Cross-Platform DB2 Stored Procedures: Building and Debugging
http://www.redbooks.ibm.com/redbooks/pdfs/sg245485.pdf
DB2 9 for z/OS Stored Procedures: Through the Call and Beyond
http://www.redbooks.ibm.com/abstracts/sg247604.html
DB2 Java Stored Procedures: Learning by Example
http://www.redbooks.ibm.com/redbooks/pdfs/sg245945.pdf
Modernizing IBM eServer iSeries Application Data Access – A Roadmap Cornerstone
http://www.redbooks.ibm.com/abstracts/sg246393.html
Improving Stored Procedure Performance 18 December 2009, Kent Milligan, Jarek
Miszczyk, and Gene Cobb http://tinyurl.com/2ayskqo
The API Corner MC Press online: Automating Recovery (or Keeping the Help Desk Out
of the Loop) 21 July 2010 – October 2010, Bruce Vining http://tinyurl.com/32gkc9h
Page 10 of 10
1/3/2011 4:49:44 PM