EMBEDDED SQL INTO RPG
Data Base Access coding choices
a)
b)
High-Level language
o READ/WRITE/UPDATE/CHAIN/UPDATE
o Embedded SQL in HLL programs
OPNQRYF
Note: Embedded SQL eliminates need for OPNQRYF and Logical
File
Why SQL in RPG?
1. Multiple row processing
2. Easy manipulation of data
3. BIFs are available (Column functions: SUM, AVG... Scalar
functions ABS, SIN.. Date functions)
4. Sorting possibilities are enhanced by sql
5. Can be easier to read and maintain
6. Query Optimizer tunes SQL based I/O
7. SQL can make code more portable
Note: SQL does not have user interface.
Source Type to embed SQL code in RPG is SQLRPG / SQLRPGLE
RPG
RPG
SQL
SQL
SOURCE
PGM
SOURCE
PREPROCESSOR
RPG
OBJECT
COMPILER
Compilation fails due to
Compilation fails due to
SQL Syntax Error
RPG Error
SQL Embedded types:1. Static statements
SQL statements known at compile time
2. Dynamic statements
SQL statements created on-the-fly during execution of
program
How to embed SQL statement in RPG III ?
C/EXEC SQL
C+
UPDATE
EMPMST
C+
SET EMPDEP = QQ
C+
WHERE EMPCDE = 250
C/END-EXEC
**Note
Only one SQL statement is allowed.
/EXEC SQL and END-EXEC are compiler directives
How to embed SQL statement in RPG IV?
EXEC SQL SET OPTION COMMIT = *NONE;
EXEC SQL UPDATE EMPMST SET EMPDEP = QQ
EMPCDE = 250;
WHERE
Host Variables
RPG program variables are used within SQL statements are
known as Host Variables.
Example:
C/EXEC SQL
C+ SET OPTION COMMIT=*NONE
C/END-EXEC
C/EXEC SQL
C+UPDATE STUMST
C+SET STUDEP = :DEPT
C+WHERE STUCDE = :CODE
C/END-EXEC
Embedded SELECT statement is different from the conventional
one.
SELECT INTO
1) Used to store only one row
2) INTO clause must list at least one host variable.
3) If no row is returned then SQL code 100 is returned.
Example
EXEC SQL SELECT STUCDE,STUNAM,STUDEP INTO
:STUCDE,:STUNAM,:STUDEP FROM STUMST WHERE
STUCDE=:STUCDE;
Dynamic SQL:
Construct SQL statement on the fly.(i.e when program runs)
Two methods of dynamic SQL are
1) EXECUTE IMMEDIATE
2) PTREPARE and EXECUTE
**Note:- Prepare takes extra time building statement but
execution runs faster.
Dynamic SQL using EXECUTE IMMEDIATE
DYNSQLSTMT = UPDATE STUDEP SET STUDEP =CIVIL WHERE
STUCDE=250 ; //Assign SQL statement to variable
EXEC SQL SET OPTION COMMIT=*NONE;
required
// Otherwise COMMIT is
EXEC SQL EXECUTE IMMEDIATE :DYNSQLSTMT ;
Dynamic SQL using PREPARE AND EXECUTE
DYNSQLSTMT = UPDATE STUDEP SET STUDEP =CIVIL WHERE
STUCDE=250 ; //Assign SQL statement to variable
EXEC SQL SET OPTION COMMIT=*NONE;
EXEC SQL PREPARE UPDSTU FROM :DYNSQLSTMT;
IF
(SQLCODE
< 0);
// SQL SYNTAX ERROR
ELSE;
// Part 1
EXEC SQL EXECUTE UPDSTU;
IF
//Part2
(SQLCODE = 100);
// NO RECORD FOUND
ELSE;
ENDIF;
PARAMETER MARKER
We can embed variable in Dynamic SQL statement using
parameter marker ?.
Example
DYNSQLSTMT=UPDATE STUDEP SET STUDEP = CIVIL WHERE
STUCDE=?;
EXEC SQL SET OPTION COMMIT=*NONE;
CODE = STUCDE // Might be coming from screen or incoming
parameter
EXEC SQL PREPARE UPDSTU FROM :DYNSQLSTMT;
IF (SQLCODE >= 0 );
EXEC SQL EXECUTE UPDSTU USING :CODE;
ENDIF;
SQL Error-handling
SQL run-time errors can be handled using SQLCDE and SQLSTT
fields.
These fields are sub fields are SQLCA data structure.
SQLCA is a special DS and it is automatically added by the
compiler when SQL code is compiled.
So no need define these fields in our program.
1) SQLCDE
SQLCODE
2)
In RPGIV
SQLSTT
SQLSTATE In RPGIV
SQL CODE
0
>0
<0
Description
No error
Warning
Severe Error
SQL STATE
00000
NOT 00000
Description
No error
Error
CURSOR
It is buffer to hold the rows (records) which are returned by
SELECT statement.
Is based on select statement only.
Allow us to data manipulation- a) AVG b) SUM
Declare as read only or updatable. Default is updatable.
CURSOR Programming steps
1) Declare cursor
2) Open cursor
3) Fetch record from cursor
4) Process the fetched row
5) Close the cursor
FETCH Position:
FETCH NEXT [FROM] cursorname INTO
........
NEXT (DEFAULT)
PRIOR
FIRST
BEFORE
(Before first row)
AFTER
(After last row)
CURRENT
(No change in position)
RELATIVE N (if N is Negative previous and Positive next)
Employee Report using SQLRPGLE:
F
EMPRPT O E
PRINTER
OFLIND(*IN99)
D EMPDS E DS
EXTNAME(EMPMST)
/FREE
WRITE HEADER;
WRITE COLHDG;
EXEC SQL
DECLARE EMPCURSOR
EMPMST
FOR READ ONLY;
CURSOR FOR SELECT
FROM
// Step 1
EXEC SQL OPEN EMPCURSOR;
// Step 2
EXEC SQL FETCH NEXT FROM EMPCURSOR INTO :EMPDS; //
Step 3
DOW (SQLCODE <> 100) ;
TOTEMP += 1;
TOTSAL +=
EMPSAL;
EXSR OVERFLOWSR;
// Handle overflow
WRITE DATA;
EXEC SQL FETCH NEXT FROM EMPCURSOR INTO :EMPDS;
ENDDO;
EXEC SQL CLOSE EMPUCURSOR; // Step 5
EXSR OVERFLOWSR;
// Handle overflow
WRITE TOTAL;
EXSR OVERFLOWSR;
// Handle overflow
WRITE FOOTER;
*INLR=*ON;
BEGSR
IF
OVERFLOWSR;
(*IN99 = *ON);
WRITE HEADER;
WRITE COLHDG;
*IN99 = *OFF;
ENDIF;
ENDSR;
/END-FREE