Presentation is loading. Please wait.

Presentation is loading. Please wait.

Embedded SQL Kevin Forsythe DMC Consulting

Similar presentations


Presentation on theme: "Embedded SQL Kevin Forsythe DMC Consulting"— Presentation transcript:

1 Embedded SQL Kevin Forsythe DMC Consulting Kevin.forsythe@dmcconsulting.com

2 Why Embed SQL in your RPG? Compile Time vs Run Time

3 Work with Members Using PDM DMC41 File...... QRPGLESRC Library.... DMCSQLLIB Position to..... Type options, press Enter. 2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename 8=Display description 9=Save 13=Change text 14=Compile 15=Create module... Opt Member Type Text SQLPROC SQLRPGLE Test program containing SQL statements SQLTEST SQLRPGLE Test program containing SQL statements STOREDPRC1 SQLRPGLE Test program containing SQL statements STOREDPRC3 SQLRPGLE Test program containing SQL statements STOREDPRC4 SQLRPGLE Test program containing SQL statements STOREDPRC5 SQLRPGLE Test program containing SQL statements TSTRPGPRC SQLRPGLE Test program containing SQL statements TSTRPGPRC2 SQLRPGLE Test program containing SQL statements More... Parameters or command ===> F3=Exit F4=Prompt F5=Refresh F6=Create F9=Retrieve F10=Command entry F23=More options F24=More keys Before you can embed SQL into your RPGIV code you have to specify the source type as SQLRPGLE. New Source Type

4 Syntax C/EXEC SQL C+ your-sql-code-here C/END-EXEC C/EXEC SQL INCLUDE member-name C/END-EXEC ?

5 Syntax Avoid creating fields that start with: 'SQ' 'SQL' 'RDI' 'DSN’ These may interfere with variable names used by the pre-compiler.

6 Host Variables :field-name RPG IV variables you can’t use as a HOST variable: Pointers Tables UDATE UDAY UMONTH UYEAR Look-ahead fields Named constants Definitions requiring the resolution of %SIZE or %ELEM

7 SQL Pre-Compiler CRTSQLxxx The pre-compiler will do the following: Looks for SQL statements and for the definition of host variables. Validates variable names and definitions used in the SQL statements. Any errors found will be included in a compile listing. Verifies that each SQL statement is free of syntax errors. Validates the syntax of each SQL statement. See the compile listing for errors. Validates the SQL statements using the description in the database. Validates table, view, and column names. If a specified table or view does not exist, or you are not authorized to the table or view, the validation will be done at run time. If the table or view does not exist at run time, an error occurs.

8 SQL Pre-Compiler SQLAID SQLABC SQLCOD - SQLCODE SQLERL SQLERM SQLERP SQLERR SQLSTT - SQLSTATE SQLWRN - SQLWARN The SQL pre-compiler adds a number of fields to your RPG IV programs. These fields are used primarily for error checking. These are covered in more detail later.

9 When compiling an RPG program that includes embedded SQL statements, some new options are provided. Commitment Control: *CHG - Objects and updated records are locked until they are committed. Uncommitted changes from other programs can be seen. *CS - Objects and updated records are locked until they are committed. Uncommitted changes from other programs can not be seen, and selected records are locked until the next record is selected. *ALL - As *CS, but records selected are locked until a COMMIT is performed. *RR - As *ALL, but tables referenced by SELECT, UPDATE, INSERT, and DELETE are locked exclusively. *NONE- Commitment control is not used. CRTSQLRPGI

10 Relational Database: *LOCAL - The SQL package information is embedded in the program. named - The SQL package will be created in the named relational database. Listing Output: *PRINT - The pre-compile listing will be printed. *NONE - No pre-compile listing is produced. CRTSQLRPGI

11 INCLUDE file: *SRCFILE - Source members referenced by SQL INCLUDES will be found in the same source file as the program source. named - Specify the file and library that source members referenced by SQL INCLUDES will be found in. CRTSQLRPGI

12 Allow copy of data: *YES - A copy of selected data is only used when necessary. *OPTIMIZE- The system will determine whether to use a copy of the selected data, or read it directly from the table. *NO - A copy of the selected data is not used. If one is required, an error will occur. CRTSQLRPGI

13 Close SQL Cursor: *ENDACTGRP - SQL cursors not explicitly closed in the program will be implicitly closed when the activation group the program is running in ends. *ENDMOD - SQL cursors not explicitly closed in the program will be implicitly closed when the module is exited. CRTSQLRPGI

14 Allow Blocking: *READ - Read only data retrievals will be blocked. This improves performance for programs reading large numbers of records. *NONE - No blocking is allowed. *ALLREAD - As read but if the commitment level is *CHG, then blocked reads may also be performed against updateable tables. However some SQL commands will not function correctly. See the help text for more information. CRTSQLRPGI

15 Delay Prepare: *YES - Prepared SQL statements are validated when they are used in an OPEN, EXECUTE, or DESCRIBE statement. *NO - Prepared SQL statements are validated by the PREPARE statement. RDB Connect Method: *DUW - Your program can be connected to multiple databases simultaneously. *RUW - The CONNECT statement will cause previous connections to be disconnected. CRTSQLRPGI

16 Package: *OBJ - The SQL package will be created with the same name as the program. named - Specify the SQL package name. IBM SQL FLAGGING: *FLAG - SQL statements will be checked to see if they conform to IBM’s SQL syntax. *NOFLAG - No checking will be done. CRTSQLRPGI

17 ANS FLAGGING: *ANS - Statements are checked to see if they conform to ANSI X3.135-1992, ISO 9075-1992, and FIPS 127.2 standards. *NONE - No checking will be done. Debugging View: *NONE - Source statements will not be available during debug. *SOURCE - Source statements will be available during debug. CRTSQLRPGI

18 User Profile: *NAMING - If the naming convention is SQL, the *OWNER will be used. If the naming convention is *SYS, *USER will be used. *USER - Authority is checked against the user profile of the user running the program. *OWNER - Authority is checked against the user profile of the user who owns the program. (Usually the programmer who compiled it. Also referred to as Adopted authority). CRTSQLRPGI

19 Dynamic User Profile: *USER - Local Dynamic SQL statements are run under the user’s profile. *OWNER - Local Dynamic SQL statements are run under the profile of the program’s owner. CRTSQLRPGI

20 ILE Review RPG IV ILE Activation Groups Modules Serive Programs Sub Procedures Built in Functions Date & Time Support New Op Codes “D” Specs

21 ILE Review Service PGM X Module D Module E Module F (NOMAIN) Sub Proc 1 Sub Proc 2 Sub Proc 3 Module A (Procedure Entry Point) Module BModule C Program Y

22 Embedding SELECT DW_ITEM S 9P 0 DW_DESC S 40 * Run the SQL select C 'ITEM?' DSPLY W_ITEM C/Exec SQL SELECT MDESC C+ INTO :W_DESC C+ FROM ITMMST C+ WHERE MITEM = :W_ITEM C/End-exec C W_DESC DSPLY C RETURN Selecting ONE field from ONE record

23 Embedding SELECT DW_ITEM S 9P 0 DW_PRICE S 7P 2 DW_DESC S 40 * Run the SQL select C 'ITEM?' DSPLY W_ITEM C/Exec SQL SELECT MDESC,MPRICE C+ INTO :W_DESC, :W_PRICE C+ FROM ITMMST C+ WHERE MITEM = :W_ITEM C/End-exec C W_DESC DSPLY C W_PRICE DSPLY C RETURN Selecting TWO fields from ONE record

24 Embedding SELECT DW_DATA E DS EXTNAME(ITMMST) * Run the SQL select C 'ITEM?' DSPLY MITEM C/Exec SQL SELECT * C+ INTO :W_DATA C+ FROM ITMMST C+ WHERE MITEM = :MITEM C/End-exec C MDESC DSPLY C MPRICE DSPLY C RETURN Selecting MANY fields from ONE record

25 Embedding INSERT There are three types of embedded INSERTS: INSERT VALUES: Adds one row to a table using the values specified. INSERT SELECT: Adds one or more rows using the results of a sub-select. INSERT n ROWS: Adds multiple rows at once using the values specified in a multiple occurrence data structure.

26 Embedding INSERT * Run the SQL INSERT W/VALUES C/Exec SQL C+ INSERT INTO CUST C+ VALUES(7, ’The Fruit Stand’,’’,’’, C+ ’Miami’,‘FL’,’’,’’) C/End-exec * Run the SQL INSERT W/SUB-SELECT C/Exec SQL C+ INSERT INTO TESTLIB/CUST C+ SELECT * FROM PRODLIB/CUST C/End-exec

27 Embedding INSERT * Run the SQL INSERT W/n ROWS DW_FIELDS DS OCCURS(10) D W_ITEM 9 0 D W_DESC 40 D W_WGT 4 2 D W_PRICE 9 2 or D W_CUST E DS EXTNAME(CUST) OCCURS(10) * Run the SQL select C/Exec SQL INSERT INTO ITMMST C+ 10 ROWS VALUES(:W_FIELDS) C/End-exec

28 Embedding UPDATE * Run the SQL UPDATE C/Exec SQL UPDATE CUST C+ SET CSTATE = ‘FL’ C+ WHERE CCITY = ‘Miami’ C/End-exec C/Exec SQL C+ UPDATE CUSTWORK SET ROW = (SELECT * FROM CUST WHERE C+ CUSTWORK.NAME = CUST.NAME) C/End-exec

29 Embedding DELETE * Run the SQL DELETE C/Exec SQL DELETE FROM CUST C+ WHERE CNUMBER = :CUSTNBR C/End-exec

30 Using PREPARE DW_SQL S 1000 DW_SELECT C ‘SELECT MITEM ’ DW_FROM C ‘FROM ITMMST ’ DW_WHERE C ‘WHERE ’ DW_FIELD S 10 DW_VALUE S 30

31 Using PREPARE C ’FIELD?' DSPLY W_FIELD C ’VALUE?' DSPLY W_VALUE C EVAL W_SQL= W_SELECT + W_FROM + C W_WHERE + W_FIELD + C ‘ = ‘ + W_VALUE OR C ‘ = ‘’’ + W_VALUE + ‘’’’

32 Using PREPARE C/Exec SQL C+ PREPARE @S1 from :W_SQL C/End-exec C/Exec SQL C+ DECLARE @C1 CURSOR FOR @S1 C/End-exec C/Exec SQL C+ OPEN @C1 C/End-exec C DOU SQLCODE <> *zero C/Exec SQL C+ FETCH @C1 INTO :W_VALUE C/End-exec C ENDDO C/Exec SQL C+ CLOSE @C1 C/End-exec

33 Using PREPARE PREPARE: An SQL statement can be entered into a character string variable. The prepare statement translates that into an executable statement. Prepare once, execute many times. The prepared statement cannot contain host variables. DECLARE: If the SQL statement is a select statement, you must declare a cursor. CURSOR: A cursor defines a result table and the current row within that table. It is read-only if data was selected from more than one table, the data was selected from a read-only table, or if the select statement used the DISTINCT keyword. (A number of other conditions could also cause the table to be read-only.) OPEN: To perform a prepared SELECT, you must open the cursor. The result table will be created and the cursor will be set to the beginning of the result table. FETCH: Use FETCH to read the next row from the result table. If you read past the end of the result table, the SQLCOD field will contain an error code of 100. CLOSE: After you have finished reading the rows from a result table, close the cursor. This will allow you to reopen it later, retrieving new results.

34 Using PREPARE * DW_SQL S 1000 DW_DELETE C ‘DELETE ’ DW_FROM C ‘FROM ITMMST ’ DW_WHERE C ‘WHERE ’ DW_FIELD S 10 DW_VALUE S 30 C ’FIELD?' DSPLY W_FIELD C ’VALUE?' DSPLY W_VALUE C EVAL W_SQL= W_DELETE + W_FROM + C W_WHERE + W_FIELD + C ‘ = ‘ + W_VALUE C/Exec SQL C+ PREPARE @S1 from :W_SQL C/End-exec

35 Using EXECUTE EXECUTE: If the prepared statement is not a SELECT, use EXECUTE to perform the statement. EXECUTE IMMEDIATE: If the character string contains no host variables or parameter markers, and is only going to be executed once, you can use EXECUTE IMMEDIATE to perform that statement.

36 Using EXECUTE C/Exec SQL C+ EXECUTE @S1 C/End-exec C/Exec SQL C+ EXECUTE IMMEDIATE :W_SQL C/End-exec EXECUTE IMMEDIATE has to use a string variable. You cannot use an expression in quotes. You must first load the variable with the SQL statement.

37 Embedding SELECT Multiple Row Fetch * Run the SQL SELECT for n ROWS DW_FIELDS DS OCCURS(10) D W_ITEM 9 0 D W_DESC 40 D W_WGT 4 2 D W_PRICE 9 2 C/EXEC SQL FETCH C1 FOR 10 ROWS C+ INTO :W_FIELDS C/END-EXEC

38 Embedding SELECT Multiple Row Fetch It is possible to read more than one record at a time, loading a MODS with values for several records at once. This is more efficient than the standard one record at a time method. Three variables will be updated in the SQLCA:  SQLERRD(3) shows the number of rows retrieved.  SQLERRD(4) shows the length of the row retrieved.  SQLERRD(5) shows 100 if the last row was read.

39 Using Parameter Markers * DW_SQL S 1000 DW_SELECT C ‘SELECT MITEM ’ DW_FROM C ‘FROM ITMMST ’ DW_WHERE C ‘WHERE MITEM = ?’ DW_VALUE S 30 C ’ITEM?' DSPLY W_VALUE C EVAL W_SQL= W_SELECT + W_FROM + C W_WHERE

40 Using Parameter Markers C/Exec SQL C+ PREPARE @S1 from :W_SQL C/End-exec C/Exec SQL C+ DECLARE @C1 CURSOR FOR @S1 C/End-exec C/Exec SQL C+ OPEN @C1 USING :W_VALUE C/End-exec C DOU SQLCOD <> *zero C/Exec SQL C+ FETCH @C1 INTO :W_VALUE C/End-exec C ENDDO C/Exec SQL C+ CLOSE @C1 C/End-exec

41 Using Parameter Markers DW_SQL S 1000 DW_DELETE C ‘DELETE ’ DW_FROM C ‘FROM ITMMST ’ DW_WHERE C ‘WHERE MITEM IN (?, ?)’ DW_VALUE1 S 30 DW_VALUE2 S 30 C ’ITEM?' DSPLY W_VALUE1 C ’ITEM?' DSPLY W_VALUE2 C EVAL W_SQL= W_DELETE + W_FROM + C W_WHERE C/Exec SQL PREPARE @S1 from :W_SQL C/End-exec C/Exec SQL EXECUTE @S1 USING :W_VALUE1, :W_VALUE2 C/End-exec

42 Using Parameter Markers DW_SQL S 1000 DW_DELETE C ‘DELETE ’ DW_FROM C ‘FROM ITMMST ’ DW_WHERE C ‘WHERE MITEM LIKE ?’ DW_VALUE1 S 30 DW_COMP S 30 VARYING C ’ITEM?' DSPLY W_VALUE1 C EVAL W_COMP = %TRIM(W_VALUE1) C EVAL W_SQL= W_DELETE + W_FROM + C W_WHERE

43 Using Parameter Markers C/Exec SQL C+ PREPARE @S1 from :W_SQL C/End-exec C/Exec SQL C+ EXECUTE @S1 USING :W_COMP C/End-exec Be careful when using LIKE with host variables or parameter markers. The embedded blanks at the end of the field will cause the LIKE to fail. Use of a variable length field will eliminate this problem

44 Using Parameter Markers Parameter markers cannot be used in all parts of an SQL statement. Here are some of the ways in which parameter markers CANNOT be used: In a select list - SELECT ? (except as a sub-query) In a Concatenation - ? || ‘FRED’ As both parts of a comparison (WHERE ? = ?) To avoid this problem use the CAST function to specify the data type of the parameter. CAST(? AS CHAR) CAST(? AS NUMERIC)

45 SQL Error Handling - SQLCA SQLCODE 0 - Success Positive - Warning Negative - Error

46 D SQLCA DS D SQLAID 1 8A D SQLABC 9 12B 0 D SQLCOD 13 16B 0 D SQLERL 17 18B 0 D SQLERM 19 88A D SQLERP 89 96A D SQLERRD 97 120B 0 DIM(6) D SQLERR 97 120A D SQLER1 97 100B 0 D SQLER2 101 104B 0 D SQLER3105 108B 0 D SQLER4109 112B 0 D SQLER5 113 116B 0 D SQLER6 117 120B 0 SQL Communications Area

47 D SQLWRN 121 131A D SQLWN0 121 121A D SQLWN1 122 122A D SQLWN2 123 123A D SQLWN3 124 124A D SQLWN4 125 125A D SQLWN5 126 126A D SQLWN6 127 127A D SQLWN7 128 128A D SQLWN8 129 129A D SQLWN9 130 130A D SQLWNA 131 131A D SQLSTT 132 136A SQL Communications Area

48 SQLERL - Contains the length of the text loaded into SQLERM. SQLERM - Contains Message text for the SQLCOD value. SQLERP - Contains the name of the Product and Module returning an error. SQLERRD - Array containing 6 diagnostic codes. (1) - Last four digits of the CPF message if SQLCOD is negative. (2) - Last four digits of the CPD message if SQLCOD is negative. (3) - For INSERT, UPDATE, DELETE, and FETCH, the number of rows affected. For PREPARE, the estimated number of rows returned. (4) - For PREPARE, the estimated cost of execution. For CALL, the message key of the error which caused the call to fail. For trigger errors during a INSERT, UPDATE, or DELETE, the message key of the error. For FETCH, the length of the row. (5) - For DELETE, the number of rows affected by referential constraints. For PREPARE or EXECUTE IMMEDIATE, the position of a syntax error. For multi-row FETCH, +100 if the last record was read. For CONNECT and SET CONNECTION, -1 if not connected, 0 if local, 1 if remote. For PREPARE, the number of parameter markers. (6) - SQL completion code when SQLCOD is 0.

49 SQL Communications Area SQLWRN - String of 11, 1 byte flags. (0) - Master flag, will contain a ‘W’ if any flags contain a ‘W’ or ‘N’. (1) - Contains a ‘W’ if a string column was truncated while being loaded into host variable. (2) - Contains ‘W’ if NULL values were eliminated from an argument of a function. (3) - Contains a ‘W’ if the number of columns exceeds the number of host variables. (4) - Contains a ‘W’ if UPDATE or DELETE do not contain a WHERE clause. (5) - Reserved. (6) - Contains a ‘W’ if date arithmetic results in an end of month adjustment. (7) - Reserved. (8) - Contains a 'W' if the result of a character conversion contains a substitution character. (9) - Reserved. (10) - Reserved. SQLSTT - A return code for the most recent SQL statement. (For detail on the SQLSTATE (SQLSTT) values, see Appendix B in manual “DB2 UDB for AS/400 SQL Programming”.) You can find more information on-line at: publib.boulder.ibm.com in the manual: DB2 for AS/400 SQL programming.

50 SQL Error Handling WHENEVER… In addition to the SQLCA, other error handling features are available. Use the SQL WHENEVER statement to set up error trapping before issuing other SQL statements. WHENEVER NOT FOUND … = IF SQLCODE = 100 WHENEVER SQLERROR … = IF SQLCOD < *ZERO WHENEVER SQLWARNING … = IF SQCOD > *ZERO and SQLCOD <> 100 The WHENEVER statement will go into effect until a new WHENEVER statement of the same type is issued. This eliminates needing to test each SQL statement for an error. In general, this function is very similar to the global MONMSG function in CL. However the statements are processed by compile in the sequence they are written, not at run time in the order they are executed. Therefor their use is discouraged.

51 * Run the SQL INSERT W/VALUES C/Exec SQL C+ WHENEVER SQLWARNING CONTINUE C/End-exec C/Exec SQL C+ WHENEVER NOT FOUND GOTO DONE C/End-exec C/Exec SQL C+ WHENEVER SQLERROR GOTO ERROR C/End-exec C DONE TAG C ERROR TAG SQL Error Handling

52 ADVANCED CURSORS SCROLL - Allows forward and back movement of the cursor. DYNAMIC SCROLL - As Scroll but also allows update. WITH HOLD - Allows COMMIT to be performed without closing the cursor.

53 In the DECLARE CURSOR statement you can add additional clauses to provide more capability within the program. By default a FETCH will perform sequential reads against the data in the specified order. Specify SCROLL to allow more flexibility in moving the cursor. Specify DYNAMIC SCROLL to allow update. Specify WITH HOLD if you want to use commitment control with the updates. ADVANCED CURSORS

54 FETCH NEXT - positions cursor ON next record. PRIOR - positions cursor ON previous record. FIRST - positions cursor ON the first record in the result table. LAST - positions cursor ON the last record in the result table. BEFORE - positions cursor BEFORE the first record in the result table. AFTER - positions cursor AFTER the last record in the result table. CURRENT - no change. RELATIVE - A negative number moves back x rows. A positive value moves forward X rows.

55 C+ DECLARE @QC1 DYNAMIC SCROLL CURSOR WITH HOLD C+ FOR SQLSTMT @S1 C+ FETCH PRIOR FROM @QC1 INTO :W_DATA1 :W_IND1, C+ :W_DATA2 :W_IND2, :W_DATA3 :W_IND3 C+ FETCH RELATIVE -1 FROM @QC1 INTO :W_DATA1 :W_IND1, C+ :W_DATA2 :W_IND2, :W_DATA3:W_IND3 C+ FETCH BEFORE FROM @QC1 C+ DECLARE @C2 DYNAMIC SCROLL CURSOR WITH HOLD FOR C+ SELECT * FROM DATA FOR UPDATE OF LONGNAM2 C+ FETCH FIRST FROM @QC2 INTO :W_FIELDS C+ UPDATE DATA SET LONGNAM2 = ‘FRED’ C+ WHERE CURRENT OF @C2 ADVANCED CURSORS

56 The FOR UPDATE OF clause in the SELECT statement indicates which columns in the table are valid for update. Specifying just FOR UPDATE will make all columns updateable. Updateable columns cannot be referenced in the ORDER BY clause.

57 SQL Commitment Control UPDATE MASTER RECORD INSERT HISTORY RECORD DELETE TRANSACTION COMMIT Commit

58 SQL Commitment Control Commitment control is used to group multiple file updates together, and treat them as a single transaction. Either they all succeed, or they all fail. This ensures data integrity even in the case of a program crash. All updates are considered tentative, until the commit is performed. The Commit command requires commitment control to be active. To determine if it is active, check each user’s Query Manager profile to determine their commitment control level. There are five different levels. Each level provides increasing levels of control.

59 1) NONE - Commitment control is not active. It is the default setting, and COMMIT and ROLLBACK cannot be used with this setting. 2) CHG - Rows that have been inserted, updated, or deleted will be locked until a COMMIT or ROLLBACK is performed. 3) CS - (Cursor Stability) As CHG, but in addition all rows selected in a WHERE clause are locked until you have scrolled past them. 4) ALL - All rows that were read, inserted, updated, or deleted are locked until a COMMIT or ROLLBACK is performed. 5) RR - (Repeatable Read) As ALL, but in addition all tables are locked. SQL Commitment Control

60 The rollback command also requires commitment control to be active. Unlike COMMIT, ROLLBACK is rarely used in SQL. The system will automatically issue a roll back when a SQL job ends abnormally, and on exit from an interactive SQL session. Be sure to COMMIT all changes, before pressing F3 to exit. Also be aware that when using commitment control in an interactive SQL session you may be keeping records locked for extended periods of time. This may interfere with other users on the system. Rollback SQL Commitment Control

61 COMMITMENT CONTROL After reading a transaction record: 1)The master file will be updated 2)A record will be added to the history file 3)The transaction record will be deleted All of these transactions will be done as a group. Either they all succeed or they all fail. This will simplify restarting the program after an error.

62 D W_FIELDS E DS EXTNAME(TRAN) D W_SQL S 1000 C EVAL W_SQL = 'SELECT * + C FROM TRAN FOR UPDATE' C/EXEC SQL WHENEVER SQLERROR GOTO ERROR C/END-EXEC C/EXEC SQL PREPARE SQLSTMT FROM :W_SQL C/END-EXEC COMMITMENT CONTROL

63 c* C/EXEC SQL C+ DECLARE @QC1 DYNAMIC SCROLL CURSOR WITH HOLD FOR SQLSTMT C/END-EXEC C/EXEC SQL C+ OPEN @QC1 C/END-EXEC C/EXEC SQL C+ FETCH NEXT FROM @QC1 INTO :W_FIELDS C/END-EXEC COMMITMENT CONTROL

64 C DOW SQLCOD = *ZERO C/EXEC SQL C+ UPDATE MAST SET OHQTY = OHQTY + :TRQTY C+ WHERE MAST.PART = :PART C/END-EXEC C/EXEC SQL C+ INSERT INTO HIST VALUES(:W_FIELDS) C/END-EXEC C/EXEC SQL C+ DELETE FROM TRAN WHERE CURRENT OF @QC1 C/END-EXEC C COMMIT C/EXEC SQL C+ FETCH NEXT FROM @QC1 INTO :W_FIELDS C/END-EXEC C ENDDO COMMITMENT CONTROL

65 C ERROR TAG C ROLBK C END TAG C/EXEC SQL C+ WHENEVER SQLERROR CONTINUE C/END-EXEC * Close SQL cursor C/EXEC SQL C+ CLOSE @QC1 C/END-EXEC C RETURN COMMITMENT CONTROL

66 C/EXEC SQL C+ UPDATE DATA SET LONGNAM2 = NULL WHERE NAME IS NOT NULL C/END-EXEC C/EXEC SQL C+ SELECT * FROM DATA WHERE LONGNAM2 IS NULL C/END-EXEC Null Values

67 NULL values are “unknown” values, not blank, not zero, not anything, simply unknown. You cannot reference the data in a field if it has a NULL value. Not all fields can contain NULL values. An even value in SQLTYPE denotes that the field can not contain NULL. An odd value denotes that NULL is allowed. SQL provides a mechanism for testing fields for NULL values. An associated indicator will be loaded with negative 1 if the field contains a NULL value, as seen on the next page.

68 * Single Row FETCH testing for NULL values DW_NAME S 30 DW_LONGNAM1 S 120 DW_LONGNAM2 S 120 DW_IND1 S 5I 0 DW_IND2 S 5I 0 C/EXEC SQL C+ FETCH NEXT FROM @QC1 INTO :W_NAME :W_IND1, C+ :W_LONGNAM1, :W_LONGNAM2 :W_IND2 C/END-EXEC Null Values

69 * Multi Row FETCH testing for NULL values DW_FIELDS DS OCCURS(10) D W_NAME 30 D W_LONGNAM1 120 D W_LONGNAM2 120 DW_IND DS OCCURS(10) D W_IND1 5I 0 D W_IND2 5I 0 D W_IND3 5I 0 C/EXEC SQL FETCH @QC1 FOR 10 ROWS C+ INTO :W_FIELDS :W_IND C/END-EXEC Null Values

70 CREATE PROCEDURE RPGPROC(IN PARM1 CHAR (30)) LANGUAGE RPGLE NOT DETERMINISTIC CONTAINS SQL EXTERNAL NAME RPGPROC PARAMETER STYLE GENERAL Stored Procedures

71 CALL RPGPROC (‘DATA’) Stored Procedures

72 How to Embed RPG in your SQL?

73 The Service Program is an extremely powerful tool for deploying applications. Essentially it allows you to extend both SQL and RPG to include new features that you need. Build Service Programs!

74 User Defined Functions (UDFs) allow you to extend the capabilities of the SQL engine, and more tightly integrate it with your database. RPG ILE is often used to develop these functions. Build User Defined Functions!

75 1)Have one binding directory for all tools – i5Tools 2)Have one copy book for all prototypes – i5Tools 3) Document Procedures in the Copy Book Keep It Simple System

76 Service Program Code ADDBNDDIRE BNDDIR(I5TOOLS) OBJ((MsgBox)) ADDBNDDIRE BNDDIR(I5TOOLS) OBJ((Dates)) ADDBNDDIRE BNDDIR(I5TOOLS) OBJ((Fetch)) CRTBNDDIR i5Tools Create Binding Directory Add Service Programs to directory

77 1)Message Box Utility 2)Get Text Descriptions of Dates 3)Perform SQL Fetch Service Program Examples

78 H NOMAIN EXPROPTS(*RESDECPOS) H OPTION(*SRCSTMT:*NODEBUGIO) FMSGBOXDF CF E WORKSTN F USROPN MsgBox Code Part 1 of 4 DMsgBox PR D Msg1 50A VALUE D Msg2 50A OPTIONS(*NOPASS) D VALUE D Msg3 50A OPTIONS(*NOPASS) D VALUE D Msg4 50A OPTIONS(*NOPASS) D VALUE

79 PMsgBox B EXPORT DMsgBox PI D Msg1 50A VALUE D Msg2 50A OPTIONS(*NOPASS) D VALUE D Msg3 50A OPTIONS(*NOPASS) D VALUE D Msg4 50A OPTIONS(*NOPASS) D VALUE MsgBox Code Part 2 of 4

80 C OPEN MSGBOXDF C Clear Text1 C Clear Text2 C Clear Text3 C Clear Text4 MsgBox Code Part 3 of 4

81 C EVAL Text1 = Msg1 C SELECT C WHEN %PARMS = 2 C EVAL Text2 = Msg2 C WHEN %PARMS = 3 C EVAL Text2 = Msg2 C EVAL Text3 = Msg3 C WHEN %PARMS = 4 C EVAL Text2 = Msg2 C EVAL Text3 = Msg3 C EVAL Text4 = Msg4 C ENDSL C EXFMT Win1 C CLOSE MSGBOXDF C Return PMsgBox E MsgBox Code Part 4 of 4

82 A R WIN1 A WINDOW(10 10 8 60- A *NOMSGLIN) A PUTOVR A WDWBORDER( - A (*COLOR BLU)- A (*DSPATR RI)- A (*CHAR ' ')) A 1 26'Message Box' A DSPATR(HI) MsgBox DDS Part 1 of 2

83 A TEXT1 50 O 3 6 A TEXT2 50 O 4 6 A TEXT3 50 O 5 6 A TEXT4 50 O 6 6 A 8 2'F12 = Cancel' A COLOR(BLU) A R DUMMY A ASSUME A 1 3' ' MsgBox DDS Part 2 of 2

84 Service Program Code CRTSRVPGM SRVPGM(MYFLIB/MsgBox) MODULE(MsgBox) EXPORT(*ALL) CRTRPGMOD MODULE(MYLIB/MsgBox) SRCFILE(MYLIB/i5Tools) SRCMBR(MsgBox) Create Module Create Service Program

85 Putting it to the test H BNDDIR(‘I5TOOLS’) /COPY i5Tools,i5Tools /FREE MsgBox(‘What a Cool Tool!’); MsgBox(‘First one line…’: ‘Then another!’); *INLR = *ON; /END-FREE

86 Putting it to the test

87 Getting Date Names

88 02/14/2006 Order 123 scheduled to ship on Tuesday Month End Close for February is Complete Shipment due for Monday, February 14 2006

89 H NOMAIN EXPROPT(*RESDECPOS) H OPTION(*SRCSTMT:*NODEBUGIO) H COPYRIGHT('DMC Consulting 2005') /COPY i5Tools,i5Tools Service Program Code Part 1 of 4 D GetDayNam PR 10 D InpDat D D GetMonNam PR 10 D InpDat D D GetDatNam PR 40 D InpDat D

90 PGetDayNam B EXPORT DGetDayNam PI 10 D Date d D Daynam S 10 C/EXEC SQL C+ SET :DayNam = DAYNAME(:Date) C/END-EXEC C return DayNam P E Service Program Code Part 2 of 4

91 Service Program Code Part 3 of 4 PGetMonNam B EXPORT DGetMonNam PI 10 D Date d D MonNam S 10 C/EXEC SQL C+ SET :MonNam = MONTHNAME(:Date) C/END-EXEC C return MonNam P E

92 Service Program Code Part 4 of 4 PGetDatNam B EXPORT DGetDatNam PI 40 D Date d D Datnam S 40 C/EXEC SQL C+ SET :DatNam = DAYNAME(:Date) || ' ' || C+ MONTHNAME(:Date) || ' ' || C+ CHAR(DAYOFMONTH(:Date)) || ', ' C+ CHAR(YEAR(:Date)) C/END-EXEC C return DatNam P E

93 Service Program Code CRTSRVPGM SRVPGM(KPFLIB/Dates) MODULE(Dates) EXPORT(*ALL) CRTRPGMOD MODULE(KPFLIB/Dates) SRCFILE(KPFLIB/i5Tools) SRCMBR(Dates) Create Module Create Service Program

94 Putting it to the test H BNDDIR(‘I5TOOLS’) /COPY i5Tools,i5Tools /FREE Date = %DATE(); DayNam = GetDayNam(DATE); MsgBox(‘Order ’ + Ordno + ‘ scheduled ’ + ‘to ship ’ + DayNam); *INLR = *ON; /END-FREE

95 Getting Date Names 02/14/2006 Order 123 scheduled to ship on Tuesday

96 Putting it to Use H BNDDIR(‘I5TOOLS’) /COPY i5Tools,i5Tools /FREE Date = %DATE(); DayNam = GetDayNam(DATE); MsgBox(‘Order ’ + Ordno + ‘ is due to ’ + ‘ship on ’ + DayNam); *INLR = *ON; /END-FREE Put these two lines in every program

97 User Defined Functions 1)Unpack Data 2)Running Totals

98 Getting Packed Data ID Customer ?General Motors ?Honda ?Toyota ?Ford ?Chrysler

99 SELECT SUBSTR(CUSTFLAT,4,30), DECIMAL(SUBSTR(HEX(SUBSTR( CUSTFLAT,1,3)),1,5),5,0) * CASE WHEN SUBSTR(HEX(SUBSTR( CUSTFLAT,3,1)),2,1) ='F' THEN 1 ELSE -1 END FROM CUSTFLAT SQL Syntax to Unpack

100 RPG Syntax to Unpack Part 1 of 2 PUnPack B DUnPack PI 15P 2 D Text 3000A Varying D Start 5I 0 D Len 5I 0 D RawDS DS D Packed 15P 0

101 RPG Syntax to Unpack part 2 of 2 *----------------------------------------------- * Load Text Into Packed Field *----------------------------------------------- C Clear Packed C EVALR %SUBST(RAWDS: C 9-Len:Len) = C %SUBST(Text:Start:Len) C Return Packed PUnPack E

102 RPG Syntax to Unpack 00000000 RawDS 0000000F 001 Text 00F 00000001 RawDS 0000000F

103 RPG Syntax to Unpack CRTSRVPGM SRVPGM(KPFLIB/UNPACK) MODULE(UNPACK) EXPORT(*ALL) CRTRPGMOD MODULE(KPFLIB/UnPack) SRCFILE(KPFLIB/i5Tools) SRCMBR(UnPack) Create Module Create Service Program

104 RPG Syntax to Unpack CREATE FUNCTION MYLIB/UnPack (IN VARCHAR(2000), IN INTEGER, IN INTEGER) RETURNS DECIMAL(15,0) EXTERNAL NAME ‘MYLIB/UNPACK(UNPACK)' LANGUAGE RPGLE PARAMETER STYLE GENERAL) Register Function With SQL (SQL CMD)

105 RPG Syntax to Unpack Select Unpack(CUSTFLAT,1,3) from CUSTFLAT Use the Function! UNPACK 00001 00002 00003 00005

106 SELECT SUBSTR(CUSTFLAT,4,30), DECIMAL(SUBSTR(HEX(SUBSTR( CUSTFLAT,1,3)),1,5),5,0) * CASE WHEN SUBSTR(HEX(SUBSTR( CUSTFLAT,3,1)),2,1) ='F' THEN 1 ELSE -1 END FROM CUSTFLAT RPG Syntax to Unpack Instead of this!

107 Running Totals 1001 10 10 1002 12 22 1003 7 29 1004 15 44 1005 11 55 Order Qty Total

108 Running Totals * Prototype for RunSum(QTY) D RunSum PR D Parm1 8F D QtyOut 8F D InNull1 5I 0 D OutNull 5I 0 D SqlState 5 D FuncName 517A VARYING D SpecName 128A VARYING D MesgText 70A VARYING D Scratch 8F D Flag 10I 0 DB2SQL Parameter style

109 Running Totals P RunSum B EXPORT D RunSum PI D QtyIn 8F D QtyOut 8F D InNull1 5I 0 D OutNull 5I 0 D SqlState 5 D FuncName 517A VARYING D SpecName 128A VARYING D MesgText 70A VARYING D Scratch 8F D Flag 10I 0

110 Running Totals * Trap for any error that occurs C MONITOR * If this is the first time it’s called * for this select, set the balance to 0 C IF FLAG = -1 C Clear Scratch C ENDIF * Add the input quantity to the scratch quantity C ADD QtyIn Scratch C Z-ADD Scratch QtyOut * Return the quantity C RETURN

111 Running Totals * If any error occurs return a zero C ON-ERROR *PROGRAM C C EVAL QtyOut = 0 C RETURN C ENDMON P E

112 Running Totals CRTSRVPGM SRVPGM(KPFLIB/RunSum) MODULE(RunSum) EXPORT(*ALL) CRTRPGMOD MODULE(KPFLIB/RunSum) SRCFILE(KPFLIB/i5Tools) SRCMBR(RunSum) Create Module Create Service Program

113 Running Totals CREATE FUNCTION your-schema/RunSum (INOUT DOUBLE) RETURNS DOUBLE EXTERNAL NAME 'your-schema/SQLFUNCS(RunSum)' LANGUAGE RPGLE PARAMETER STYLE DB2SQL NOT DETERMINISTIC SCRATCHPAD 8 FINAL CALL DISALLOW PARALLEL) Register Function With SQL (SQL CMD)

114 Running Totals Select Order, Qty, Runsum(Qty) from ORDMAST Use the Function! 1 10 10 1001 12 22 1002 7 29 1003 15 44 1004 11 55 Order Qty Total

115 Canned SQL 1)Fetch This!

116 1)Easy Load all Subfile Canned SQL

117 RPG Syntax to Fetch H EXPROPTS(*RESDECPOS) BNDDIR('I5TOOLS') H DFTACTGRP(*NO) ACTGRP(*NEW) H OPTION(*SRCSTMT:*NODEBUGIO) FSAMPSUBDF CF E WORKSTN PREFIX(S_) F SFILE(SUBFILE:SflRRN) *--------------------------------------------------------

118 RPG Syntax to Fetch /COPY i5Tools,i5Tools D RefDS E DS EXTNAME(Reffile) D Prefix(Ref) D Based(Ptr_Not_Used) D PTR S * INZ(%ADDR(*IN)) D INDARRAY DS BASED(PTR) D Exit 03 03N D SflDsp 10 10N D SflDspCtl 11 11N D SflEnd 14 14N

119 RPG Syntax to Fetch D Stmt S 512 D SflRRN S 4S 0 D NumRows S 4S 0 * D Cust DS Qualified D CNumber LIKE(RefCnumber) D CName LIKE(RefCname)

120 RPG Syntax to Fetch *-------------------------------------------------------- * Load SQL Results into subfile *-------------------------------------------------------- C CALLP Fetch('Select Cnumber,Cname + C from Cust': NumRows) C DoW SflRRN < NumRows C CALLP Load(Cust) C EVAL SflRRN = SflRRN + 1 C Eval S_CName = Cust.CName C Eval S_CNumber = Cust.CNumber C Eval S_Opt = *BLANK C Write SUBFILE C Enddo

121 RPG Syntax to Fetch C EVAL SflDspCtl = *ON C EVAL SflDsp = *ON C EVAL SflEnd = *ON C EVAL S_S@RRN = 1 C DoU Exit C Write FKeys C Exfmt Control C Enddo C Eval *INLR = *ON C Return

122 Dynamic SQL Syntax C/Exec SQL C+ PREPARE stmt1 from :W_SQL C/End-exec C/EXEC SQL C+ DESCRIBE Stmnt1 INTO :SQLDA C/END-EXEC Select Cnumber,Cname from Cust SQLVAR Array Field Type Field Length Pointer to Data

123 Dynamic SQL Syntax DSQLDA DS D SQLDAID 8A D SQLDABC 10I 0 D SQLN 5I 0 D SQLD 5I 0 D SQLVAR 80A DIM(120) D SQLTYPE 5I 0 OVERLAY(SQLVAR:1) D SQLLEN 5I 0 OVERLAY(SQLVAR:3) D SQLRES 12A OVERLAY(SQLVAR:5) D SQLDATA * OVERLAY(SQLVAR:17) D SQLIND * OVERLAY(SQLVAR:33) D SQLNAMELEN 5I 0 OVERLAY(SQLVAR:49) D SQLNAME 30A OVERLAY(SQLVAR:51)

124 Dynamic SQL Syntax C EVAL RowLen = 0 C DO SQLD X C SELECT * Small Integer C WHEN SQLTYPE(X) = 500 C EVAL W_Len = 2 * Large Integer C WHEN SQLTYPE(X) = 496 C EVAL W_Len = 4

125 Dynamic SQL Syntax * Zoned decimal format C WHEN SQLTYPE(X) = 488 C SQLLEN(X) DIV 256 W_LEN C EVAL W_Len = %INT(%DEC( C W_Len / 2:7:1) + 1) * Packed decimal format C WHEN SQLTYPE(X) = 484 C SQLLEN(X) DIV 256 W_LEN

126 Dynamic SQL Syntax C/EXEC SQL C+ FETCH @C1 USING DESCRIPTOR :SQLDA C/END-EXEC Col 1Col 2Col 3 SQLVAR(1)SQLVAR(2)SQLVAR(3) Fetch 1 row of data into SQLVAR

127 Dynamic SQL Syntax Col 1Col 2Col 3 Concatenate all columns Row Data

128 Dynamic SQL Syntax Pointer to Data Pointer to Next Elem. Pointer to Data Pointer to Next Elem. Pointer to Data Pointer to Next Elem. Pointer to Data Pointer to Next Elem. Pointer to Data Pointer to Next Elem.

129 Dynamic SQL Syntax RsltData (1 st address) CUST DS CNUMBER CNAME

130 Why?

131 Simpler Applications… C CALLP Fetch('Select Cnumber, + C Cname from Cust': NumRows) C DoW SflRRN < NumRows C CALLP Load(Cust) C EVAL SflRRN = SflRRN + 1 C Eval S_CName = Cust.CName C Eval S_CNumber = Cust.CNumber C Eval S_Opt = *BLANK C Write SUBFILE C Enddo

132 Embedded SQL w/o Precompiler Avoid Record format Level checks Dynamic sort and selection options Just a starting point for your own tools…

133 1)Fetch and Throw! To the Web!

134 1)Easy web display Canned SQL

135 RPG Syntax to Web H EXPROPTS(*RESDECPOS) BNDDIR('I5TOOLS') H ACTGRP(*NEW) DFTACTGRP(*NO) /copy CGIDEV2/qrpglesrc,hspecs /copy CGIDEV2/qrpglesrc,hspecsbnd *================================================== * Includes to be used in CGIs *================================================== /copy CGIDEV2/qrpglesrc,prototypeb /copy CGIDEV2/qrpglesrc,usec /copy CGIDEV2/qrpglesrc,variables3 *================================================== /COPY i5Tools,i5Tools

136 RPG Syntax to Web D RefDS E DS EXTNAME(Reffile) D Prefix(Ref) D Stmt S 512 D X S 4S 0 D NumRows S 4S 0 * D Customer DS Qualified D CNumber LIKE(RefCnumber) D CName LIKE(RefCname)

137 RPG Syntax to Web * Main line *================================================== C CALLP DoCmd('ADDLIBLE KPFLIB') C CALLP DoCmd('ADDLIBLE + C CGIDEV2') /copy CGIDEV2/qrpglesrc,prolog3 * Load HTML C callp gethtml('HTMLSRC': C 'KPFLIB':'SAMPWEB2') * C callp wrtsection('top') * C CALLP Fetch('Select Cnumber, + C Cname from Cust’: C NumRows)

138 RPG Syntax to Web C DoW X < NumRows C Add 1 X C CALLP Load(Customer) C callp updhtmlvar('cnumber': C %Char(Customer.Cnumber)) C callp updhtmlvar('cname': C Customer.CName) C callp wrtsection('row') C Enddo C callp wrtsection('bottom') C callp wrtsection('*fini') C Eval *INLR = *ON C Return

139 HTML Syntax Sample Web Page One <FORM NAME="SELECT" method="POST" action="/kpflib/sampweb.pgm"> Customer Data Display Customer Data First Page

140 HTML Syntax /$top Customer List Customer List Cus. Nbr Customer Name Second Page (1 of 2)

141 HTML Syntax /$row /%cnumber%/ /%cname%/ /$bottom Second Page (2 of 2)

142 Canned SQL

143 Performance ? Indexes –Creation Order Key Sequence Index Type Use EVI Optimizer Time Out Visual Debug Coding Techniques

144 Performance There are often times many different ways to achieve the results you desire. Some will be more efficient than others. This example illustrates using a sub-select to generate the value of a single column. This is not a very efficient technique. This more complex example shows how to join a file to a temporary sub-total file generated by a sub-select over the same file.

145 Performance This additional example illustrates the WITH clause and a prelude to the SELECT statement. It predefines the sub-select as a temporary table object, and in many cases can greatly simplify the code in the rest of the select statement. The second and third example are similar from a performance standpoint. But this last example is the better choice in general.

146 Performance Another way to improve performance is by limiting the number of records selected. Add the FETCH FIRST x ROWS ONLY clause. In Embedded SQL statements, if you will be processing the result set in groups of a certain number of records. You may wish to add the OPTIMIZE clasue.

147 SQE vs CQE CQE - is an older less efficient version of the SQL engine – it does however support some features which the newer SQE engine does not. SQE – is the latest and most advanced SQL engine available for the iSeries. There are some features which it does not yet support though, and SQL commands utilizing such features will be rerouted to the CQE engine. By default the SQE engine will not process files with logical files which include Select/Omit statements. To instruct the SQE engine to ignore these logical files ensure that your copy of the QAQQINI file has the parameter: IGNORE_DERIVED_INDEX set to *YES. See more info at http://www-03.ibm.com/servers/eserver/iseries/db2/sqe.html

148 Additional Resources IBM Database Homepage: http://www-03.ibm.com/servers/eserver/iseries/db2/http://www-03.ibm.com/servers/eserver/iseries/db2/ IBM SQE Documentation: http://www-03.ibm.com/servers/eserver/iseries/db2/sqe.htmlhttp://www-03.ibm.com/servers/eserver/iseries/db2/sqe.html IBM Info Center: http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsphttp://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp SQL Book (Shameless self promotion): http://www.mc-store.com/5063.htmlhttp://www.mc-store.com/5063.html Contact me for additional help or information on additional training options. You can reach me at: Kevin.forsythe@dmcconsulting.comKevin.forsythe@dmcconsulting.com, or call me at (419) 535-2900.

149 Why Embed SQL in your RPG? COMPILE TIME Vs. RUN TIME F Specs


Download ppt "Embedded SQL Kevin Forsythe DMC Consulting"

Similar presentations


Ads by Google