+ All Categories
Home > Documents > Embedding SQL in RPG

Embedding SQL in RPG

Date post: 23-Apr-2017
Category:
Upload: srikanth-marneni
View: 232 times
Download: 3 times
Share this document with a friend
23
Embedding SQL in RPG
Transcript
Page 1: Embedding SQL in RPG

Embedding SQL in RPG

Page 2: Embedding SQL in RPG

Why SQL?• SQL is the IBM standard for relational database access• SQL is the industry standard for relational database access• SQL is the defacto standard for Client/Server data retrieval

– Don’t ask me what that means – it was in an IBM-supplied slide

Page 3: Embedding SQL in RPG

SQL Terms

System Name Related SQL TermLibrary SchemaPhysical File TableRecord Row Field Column

Page 4: Embedding SQL in RPG

SQL Commands• SELECT

– Retrieves data from a file (or table in SQL terms)• UPDATE

– Updates a record (row) in a file (table)• DELETE

– Deletes a record (row) from a file (table)• INSERT

– Adds a record (row) to a file (table)

Full disclosure: I have not used the UPDATE, DELETE, or INSERT commands in an RPG program yet. (Perhaps Tony has and can share some info with us.)

Page 5: Embedding SQL in RPG

Additional SQL Functions• DECLARE (CURSOR)

– Sets the “rules” for what data will be included in the temporary result table and how to sequence it

– Similar to the FILE, QRYSLT and KEYFLD keywords on an OPNQRYF in a CL program

• OPEN and CLOSE (CURSOR)– Opens and closes the temporary result table– Similar to the OVRDBF, OPNQRYF, and CLOF statements in a CL program

• FETCH– Retrieves data from the temporary result table– Similar to the READ or READP Op-Codes in RPG

• COMMIT/ROLLBACK (journaling functions) and GRANT/REVOKE (security functions) will not be addressed in this session (primarily because I have not used them to this point).

Page 6: Embedding SQL in RPG

RPG Source Types• SQLRPGLE• SQLRPG

• This option (embedded SQL) is not automatically included in the iSeries OS• It is a billable add-on• If your system does not allow it, you can create the source, but you can’t compile them. You can

run the compiled objects if they are compiled on a system that does allow it.

• These source types go through a “pre-compiler” that parses (interprets) the SQL statements before compiling the RPG code.

Page 7: Embedding SQL in RPG

Compiler Directives• SQL Commands are embedded between 2 compiler directives

– C/EXEC SQL– C+ Place your– C+ SQL command– C+ here– C/END-EXEC

Page 8: Embedding SQL in RPG

The DECLARE Functiond dsd empnbr 1 5 0d empnam 6 30d empdpt 31 33 0

c/exec sqlc+ DECLARE emp_cursor CURSOR for SELECT nbr, nam, dpt INTO :empnbr,c+ :empnam, :empdpt FROM empmas WHERE mar_stat = ‘M’ ORDER BYc+ dpt, namc/end-exec

• Program variables must be preceded by a colon • The INTO clause identifies where the data from the retrieved fields (columns) will be stored

– Can be specified here or on the FETCH statement• The WHERE clause identifies records to be retrieved (QRYSLT)• The ORDER BY clause identifies sorting criteria (KEYFLD).

– ORDER BY dpt DESCEND

Page 9: Embedding SQL in RPG

Additional DECLARE Options• FOR UPDATE OF (Field Name)

– Default is ALL columns (fields) can be updated and ALL rows (records) can be deleted– FOR UPDATE OF lists the columns that are to be updated

• Columns listed in the ORDER BY clause may not be listed in the FOR UPDATE OF clause

• FOR READ ONLY– Specifies no updating/deleting allowed– May improve performance

• WITH HOLD– Default: Cursors close when Commit/Rollback commands execute– WITH HOLD keeps the cursor open

Page 10: Embedding SQL in RPG

The OPEN Functionc/exec sqlc+ OPEN emp_cursorc/end-exec

Page 11: Embedding SQL in RPG

The FETCH Functionc/exec sqlc+ FETCH NEXT FROM emp_cursorc/end-exec

As mentioned earlier, the INTO clause can also be used here

c/exec sqlc+ FETCH NEXT FROM emp_cursor INTO :empnbr, :empnam, :empdptc/end-exec

• Make sure your fields on the SELECT match your fields on the INTO

Page 12: Embedding SQL in RPG

Additional FETCH OptionsAlternatives to NEXT

• PRIOR Retrieves the row before the current row• FIRST Retrieves the first row• LAST Retrieves the last row• BEFORE Positions the cursor before the first row (do NOT use INTO)• AFTER Positions the cursor after the last row (do NOT use INTO)• CURRENT Retrieves the current row (no change in cursor position)• RELATIVE n If n < -1 Retrieves the nth row before the current row

If n = -1 Same as PRIORIf n = 0 Same as CURRENTIf n = 1 Same as NEXT If n > 1 Retrieves the nth row after the current row

Page 13: Embedding SQL in RPG

DECLARE for FETCH PRIORc/exec sqlc+ DECLARE emp_cursor SCROLL CURSOR for SELECT nbr, nam, dpt INTO

:empnbr,c+ :empnam, :empdpt FROM empmas WHERE mar_stat = ‘M’ ORDER BYc+ dpt, namc/end-exec

SCROLL makes it possible for you to read forward or backward.

Page 14: Embedding SQL in RPG

Example of RELATIVEc/exec sqlc+ FETCH RELATIVE 5000 FROM emp_cursorc/end-exec

Same as…

c do 5000c/exec sqlc+ FETCH NEXT FROM emp_cursorc/end-execc enddo

Page 15: Embedding SQL in RPG

FETCH and data structuresD emp_ds dsD 1 5 0 nbrD 6 30 nameD 31 31 job

c/exec sqlC+ declare emp_cursor cursor for select emp_nbr, emp_name, emp_jobC+ from empc/end-exec c/exec sqlC+ FETCH NEXT FROM emp_cursor INTO :empdsc/end-exec

Full disclosure: I haven’t tried this either. IBM’s slide says it should work.

Page 16: Embedding SQL in RPG

UPDATE• As I said earlier, I haven’t used this command in an RPG program myself

yet, but I found an example:

c/exec sqlc+ update empc+ set sal = sal + :raisec+ where current of empcsrc/end-exec

Will update the currently read record, by adding a program field called raise to the file field called sal

Page 17: Embedding SQL in RPG

The CLOSE Functionc/exec sqlc+ CLOSE emp_cursorc/end-exec

Page 18: Embedding SQL in RPG

Error Detection & HandlingThe field SQLCODE stores a return code after every SQL command is

executed:• = 0 Successful statement execution• > 0 Successful statement execution, with warning condition• < 0 Unsuccessful statement execution

The value indicates the exact condition:• 100 = Row not found• -522 = Not authorized to object

Page 19: Embedding SQL in RPG

Error Detection (Cont’d)WHENEVER statement checks the SQLCA (SQL Communications Area) and

can branch to a location based on a condition. There are 3 conditions:• SQLWARNING (SQLCODE > 0 but not = 100)• SQLERROR (SQLCODE < 0)• NOT FOUND (SQLCODE = 100)

And 2 possible actions:• CONTINUE• GO TO

• c/exec sql• c+ FETCH NEXT FROM emp_cursor INTO :empds where emp_nbr = 500• c+ WHENEVER NOT FOUND GO TO not_found_tag• c/end-exec

Page 20: Embedding SQL in RPG

Error Detection (Cont’d)Check for an error after every command:

c/exec sqlc+ FETCH NEXT FROM emp_cursor INTO :empds where emp_nbr = 500c/end-exec

C if sqlcode <> 0C exsr sr_errC endif

Page 21: Embedding SQL in RPG

Dynamic SQLWhat is Dynamic SQL?• SQL statements are not predefined in program

– Dynamically created on the fly as part of program logic

• PREPARE statement can be used in program logic to compile dynamically created SQL statements

• Used when run time variables are involved in the selection process or the exact syntax of an SQL statement cannot be pre-determined for any other reason

• Since dynamic SQL statements did not go through the precompiler, they need to be interpreted and executed within the program – this can make them resource intensive.

Page 22: Embedding SQL in RPG

400 d SQL_ok c coost)0)500 d SQL_more s n inz(*on)600 d SQL stmt s 500 inz)’select esbnr, eeleb, aspack,700 d esupc, essc, asmcd, esbri, aslaei,800 d asbez, es esdnr from artmep900 d where’)10001100 * Declare SQL Cursor1200 c/exec sql1300 c+ declare artmap cursor scroll cursor for sl1400 c/eod-exec15001600 c eval SQL stmt %trimr(SQLstmt) + ‘ ‘ +1700 c ‘ASFL = ‘‘‘ + scfleg +1800 c eval curr group = 119002000 c select2100 c when scselt = ‘P2200 c evel SQL stmt = %trimr(SQLstmt) + ‘ end ‘ +2300 c ‘ASEG between 700 and 799’2400 c when scselt = ‘B’2500 c eval SQL stmt %trimr(SQLstmt) + end ‘ +2600 c ‘ASEG not between 700 and 799’2700 c endsl28002900 c if scquel <> *blenks3000 c eval SQL stmt = %trimr(SQLstmt) + ‘ and ‘ +3100 c ‘ASMCD = ‘ ‘ ‘ + scqual + ‘ ‘3200 c endif33003400 c if scwid c> 03600 c eval SQL stmt = %trimr(SQLstmt) + ‘ and ‘ +3600 c ‘ASBNI = ‘ + scwidalph3700 c endif38003900 c if eden <> 04000 c eval SQL stmt = %trimr(SQLstmt) ÷ ‘ and ‘ +4100 c ‘ASLAEI ‘ + sclenalph4200 c endif43004400 c if sclicn c> 04500 c eval SQL stmt = %trimr(SQLstmt) + ‘ and ‘ +4600 c ‘ASLIZD = ‘ + sclicnalph4700 c endif48004900 c if scstyl c>6000 c eval SQL stmt = %trimr(SQLstmt) ÷ ‘ and ‘ +5100 c ‘ASSNR = ‘ ‘ ‘ + scstyl ÷ ‘ ‘ ‘5200 c endif

Page 23: Embedding SQL in RPG

7700 *Prepare variable SQL statement7800 c/exec sql7900 c+ prepare s1 from :SQL_stmt8000 c/end-exec

The DECLARE statement declared a cursor called ARTMAP, so you would perform your FETCH from ARTMAP just as if this had been a pre-defined select statement instead of a prepared one.


Recommended