Add Power to RPG 400 With Embedded SQL

Embed Size (px)

Citation preview

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    1/12

    Add Power to RPG/400 With Embedded SQL

    Contributed by Richard ShalerSaturday, 31 October 1992Last Updated Saturday, 31 October 1992

    Rev up RPG/400 with embedded SQL's data manipulation capabilities.

    Also Known As... In this article, the following terms can be used interchangeably:

    SQL Terminology OS/400 TerminologyTABLE Physical FileROW RecordCOLUMN FieldINDEX Logical File

    SQL keywords are capitalized for emphasis when referenced throughout the article. SQL is not case sensitive.Brief: Ifyou've been shying away from the power of SQL in your RPG programs, fear no more. Here's an easy primer forembedded SQL.

    Those of you using SQL know how easy it is to use for impromptu requests. SQL helps to reduce your programmingbacklog by allowing some end users to retrieve information on their own, and many programmers use it for quick updatesto databases. Using a technique known as embedded SQL, you can extend the powerful data manipulation capabilitiesof SQL to your high-level language (HLL) programs.

    For example, you can create tables (physical files) and indexes (logical files), select and order, update, delete and addrecords to any file on your system. As of V2R1M1, you can perform date and time arithmetic and comparison operations.

    You can even retrieve and manipulate data on remote databases. In fact, embedded SQL could replace much of yourbasic HLL database I/O. With a few brief SQL statements, you can accomplish what might otherwise take severalprograms and considerably more cryptic code.

    A little skeptical? Perhaps the best way to make the case for embedding SQL statements in your RPG/400 programs isto see it in action. Let's dissect a situation as it is handled with traditional programming techniques as compared toembedded SQL.

    Here's the set-up: a user selects customers to be included in an order report. He also selects a sort sequence of eithercustomer name or number. The conventional programming approach to this problem might be:

    1. Create an interactive RPG/400 subfile program to present an alphabetic listing of customer names for the user tochoose from.

    2. Pass the information created by the user's selections to an Open Query File (OPNQRYF) command to create a viewof the customer information.

    3. Call another RPG/400 program to process the records selected by the OPNQRYF command and print the report.

    4. Create a CL program to act as a driver and perform the program calls.

    With embedded SQL, the steps can be simplified so that one program can easily handle it all, as illustrated by thefollowing logic:

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    2/12

    1. Create an interactive RPG/400 subfile program for the user selections.

    2. Within this program, an SQL statement is built from the user's choices and executed to select and order the records.

    3. Another SQL statement re-trieves the records (one at a time) to provide the data for the report.

    Before You Start Coding

    Embedded SQL can be a natural part of developing RPG/400 programs. There are just a few simple rules to keep inmind.

    In order for an RPG/400 program to process SQL statements, you must designate the program source member astype SQLRPG and compile it with the Create SQL RPG Program (CRTSQLRPG) command. A precompiler analyzesand converts your embedded SQL statement into RPG/400 operations that the compiler can understand.

    The precompiler also generates an SQL communications area, used to pass information to your program about themost recently executed SQL statement. If you look at your compile listing, you'll notice a data structure, SQLCA, whichdefines the SQL communication variables. For more information, refer to the AS/400 SAA SQL/400 Reference manual.

    In those programs where you need explicit control over file record I/O, SQL would not be a substitute. For example, ifyou need to read previous or read previous equal records, you will need to use RPG/400 I/O operations. EmbeddedSQL can only read sequentially forward through the records selected.

    Embedded SQL does not offer the session services you get with interactive SQL. For example, interactive SQLprovides output device support which will send and format the data from a SELECT statement to the display, a printer

    or a database file. Embedded SQL will not present a formatted display or create a report-it simply returns data to yourprogram. You must explicitly manipulate and control the data to obtain the output you want.

    Although SQL can be embedded in other languages such as COBOL, C, FORTRAN and PL/I, examples in this article arelimited to RPG/400. Using SQL in the other languages is so similar that what is shown here can be easily applied to theother languages. Refer to the AS/400 SAA SQL/400 Programmer's Guide for your particular language.

    A Blueprint for Coding SQL

    SQL statements can be added to your RPG/400 programs by coding special entries in the C-specs. Each embedded

    statement in RPG/400 is preceded by an Execute SQL statement and followed by an End Execute statement.

    To begin an SQL statement, code a 'C' in position 6, a '/' in position 7 and EXEC SQL beginning in position 8. Position 16must be blank. The SQL statement may start in position 17 and go through position 74 of this statement. The statementlooks like this:

    ... 1 ...+... 2 ...+... 3 ...+...C/EXEC SQL (SQL statement can start here)

    I normally don't start my SQL statement on the EXEC SQL statement; instead, I place it on a continuation line. Theembedded SQL statement continuation line requires a 'C' in position 6, a '+' in position 7 and a blank in position 8. TheSQL statement itself can be coded in mixed case between positions 9 and 74. It looks like this:

    ... 1 ...+... 2 ...+... 3 ...+...C+ SELECT * from Master

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    3/12

    If a statement needs to be continued, just create another continuation line and start with the next word of the statement.The End Execute statement is much like the Execute statement, except you code END-EXEC beginning in position 8.Positions 16 through 74 must be blank. It looks like this:

    ... 1 ...+... 2 ...+... 3 ...+...

    C/END-EXEC

    Comments can be included between the EXEC SQL and the END-EXEC by simply placing an asterisk (*) in position 7.

    Together the group looks like this:

    C/EXEC SQL* An RPG/400 commentC+ SELECT * FROM CSTMSTC+ WHERE BALDUE >= 100.00

    *C/END-EXEC

    Only one SQL statement can be placed between the /EXEC SQL and /END-EXEC, but it can be quite complex andnormally requires several continuation lines. This is known as a static SQL statement because it is hard-coded. The onlyway it can be changed is by editing the source member and recompiling the program.

    Static statements can contain program variables to allow value substitution. For example, let's say you want to SELECTall records with a balance due that is greater than or equal to an amount a user has submitted to your program. The SQLstatement would look like this:

    C/EXEC SQLC+ SELECT * FROM CSTMSTC+ WHERE BALDUE >= :CMBALC/END-EXEC

    The RPG/400 program variable name CMBAL is preceded by a colon (:). The colon is used here much like theampersand (&) in a CL program to indicate a variable. There is a field defined in the RPG/400 program called CMBALthat contains the value to be substituted in the SQL statement. In this case, CMBAL was defined in a display file thatprompted the user for a balance due figure.

    Since SQL works with sets of records and RPG/400 can only work with one record at a time, we have a problem. Tosolve it, we declare and use a record pointer in the program to access one record at a time from the set that SQLpresents. SQL refers to this pointer as a cursor. There are four SQL statements related to cursor usage as illustrated in1. The most important of these statements is the FETCH cursor INTO. It tells SQL to pass information into the programvariable name(s) specified after the INTO clause.

    Since SQL works with sets of records and RPG/400 can only work with one record at a time, we have a problem. Tosolve it, we declare and use a record pointer in the program to access one record at a time from the set that SQLpresents. SQL refers to this pointer as a cursor. There are four SQL statements related to cursor usage as illustrated inFigure 1. The most important of these statements is the FETCH cursor INTO. It tells SQL to pass information into theprogram variable name(s) specified after the INTO clause.

    Let's look at an example of retrieving a record by examining 2. We start by declaring a cursor we call REC_PTR for theSQL statement to be executed. (The cursor name is an SQL identifier; therefore, we are able to use the underscore inthe name.) Next, we open the cursor, FETCH the current record and place the columns CMNBR and CMNAME INTO the

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    4/12

    program variables (RPG/400 fields) @CNBR and @CNAME. Here is an important rule to remember about the FETCHstatement: You must FETCH INTO the same number of program variables as col-umns you selected in the SQLSELECT statement. In our example in 2, we are SELECTing two columns and FETCHing INTO two fields. If many fieldsare being used, you can simplify things by creating a data structure made up of the fields you will fetch INTO. Then youcan FETCH INTO the data structure name.

    Let's look at an example of retrieving a record by examining Figure 2. We start by declaring a cursor we call REC_PTR

    for the SQL statement to be executed. (The cursor name is an SQL identifier; therefore, we are able to use theunderscore in the name.) Next, we open the cursor, FETCH the current record and place the columns CMNBR andCMNAME INTO the program variables (RPG/400 fields) @CNBR and @CNAME. Here is an important rule to rememberabout the FETCH statement: You must FETCH INTO the same number of program variables as col-umns you selected inthe SQL SELECT statement. In our example in Figure 2, we are SELECTing two columns and FETCHing INTO twofields. If many fields are being used, you can simplify things by creating a data structure made up of the fields you willfetch INTO. Then you can FETCH INTO the data structure name.

    You can define more than one cursor, but each cursor requires a different name and its own:

    DECLARE CURSOR statement.

    OPEN statement.

    FETCH statement.

    CLOSE statement.

    3 illustrates a complete RPG/400 program that uses an embedded static SQL statement. The external data structuredefined as INREC uses the CSTMST file definition to easily define every field used in the CSTMST record. Since this

    example selects all columns (SELECT *), we can FETCH INTO data structure INREC because it contains all the fields forthe record format of file CSTMST, resulting in an equal number of columns and program variables. The FETCH iscontained within a loop which executes until the end of file is reached (SQLCOD field is not zero). As mentioned earlier,the precompiler supplies the SQLCOD field to your program through the SQLCA data structure. The SQLCA datastructure always contains information about the last SQL statement executed in your program.

    Figure 3 illustrates a complete RPG/400 program that uses an embedded static SQL statement. The external datastructure defined as INREC uses the CSTMST file definition to easily define every field used in the CSTMST record.Since this example selects all columns (SELECT *), we can FETCH INTO data structure INREC because it contains allthe fields for the record format of file CSTMST, resulting in an equal number of columns and program variables. TheFETCH is contained within a loop which executes until the end of file is reached (SQLCOD field is not zero). Asmentioned earlier, the precompiler supplies the SQLCOD field to your program through the SQLCA data structure. The

    SQLCA data structure always contains information about the last SQL statement executed in your program.

    This program accepts a character string through an entry parameter and accesses every customer record with acustomer address that contains the string submitted by the user. We simply use the SQL LIKE predicate (a predicateexpresses a comparison) and pass the character string to be searched for, using program variable STR. If you're notfamiliar with LIKE, check it out. It's very useful for flexible searches. Notice that the four SQL statements shown in 1 areused in the program. The program in 3 could be used by a typical subfile program to display records that match a user-submitted pattern. Since RPG/400 is not reading the customer master file, it has no F-spec for it. Input is handled bySQL.

    This program accepts a character string through an entry parameter and accesses every customer record with acustomer address that contains the string submitted by the user. We simply use the SQL LIKE predicate (a predicateexpresses a comparison) and pass the character string to be searched for, using program variable STR. If you're notfamiliar with LIKE, check it out. It's very useful for flexible searches. Notice that the four SQL statements shown in Figure1 are used in the program. The program in Figure 3 could be used by a typical subfile program to display records thatmatch a user-submitted pattern. Since RPG/400 is not reading the customer master file, it has no F-spec for it. Input is

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    5/12

    handled by SQL.

    Dynamic Embedded SQL

    Embedded SQL can also be dynamic, which means that the SQL statement is submitted and prepared at run timeinstead of at precompile time like the static statements. For instance, a free-form display file can allow a user to key a

    complete SQL statement into an input field. The statement is received by the RPG/400 program, which executes SQL toanalyze and interpret what the user keyed to determine if the statement is valid. Because it is created on the fly, dynamicSQL imposes some limitations on the SQL statements that can be used. 4 lists the SQL statements that are not valid orhave limitations as dynamic statements. But, as you will see, there is still plenty of power to consider. With dynamic SQLstatements, your program can:

    Embedded SQL can also be dynamic, which means that the SQL statement is submitted and prepared at run timeinstead of at precompile time like the static statements. For instance, a free-form display file can allow a user to key acomplete SQL statement into an input field. The statement is received by the RPG/400 program, which executes SQL toanalyze and interpret what the user keyed to determine if the statement is valid. Because it is created on the fly, dynamicSQL imposes some limitations on the SQL statements that can be used. Figure 4 lists the SQL statements that are notvalid or have limitations as dynamic statements. But, as you will see, there is still plenty of power to consider. With

    dynamic SQL statements, your program can:

    Build or accept as input an SQL statement.

    Prepare the SQL statement for running.

    Run the SQL statement.

    Handle SQL return codes.

    A dynamic SQL statement can be executed one of two ways: 1) Prepare the statement with the PREPARE statementand then execute it with the EXECUTE statement, or 2) Prepare and execute it with the EXECUTE IMMEDIATEstatement.

    The PREPARE statement analyzes and interprets the SQL statement at run time, making it ready for execution. If anerror is found in the statement, the SQL variable SQLCOD (obtained from the SQLCA data structure) will be non-zero (anegative value indicates the statement was not executed; a positive number indicates successful execution, but warningconditions exist).

    Dynamic SQL statements are divided into two types: SELECT statements and non- SELECT statements. Examples ofnon-SELECT statements include INSERT, DELETE and UPDATE. We'll look at the non-SELECT statements first byexamining a typical scenario: A user requests customer memos to be deleted from the CSTMEM file if the memo date,CMDATE, predates January 1, 1985. A user keys the SQL statement in 5 into the display file input field, USRINP, whichis referenced in the PREPARE statement, as illustrated in 6. The program could just as easily execute other SQLstatements such as INSERT, UPDATE, CREATE TABLE or CREATE INDEX.

    Dynamic SQL statements are divided into two types: SELECT statements and non- SELECT statements. Examples ofnon-SELECT statements include INSERT, DELETE and UPDATE. We'll look at the non-SELECT statements first byexamining a typical scenario: A user requests customer memos to be deleted from the CSTMEM file if the memo date,CMDATE, predates January 1, 1985. A user keys the SQL statement in Figure 5 into the display file input field, USRINP,which is referenced in the PREPARE statement, as illustrated in Figure 6. The program could just as easily execute otherSQL statements such as INSERT, UPDATE, CREATE TABLE or CREATE INDEX.

    Dynamic SELECT Statements

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    6/12

    Dynamic SELECT statements fall into two categories: fixed-list and varying- list. Fixed-list statements are those thatretrieve a predictable number and type of columns. They must always contain a set number of columns which must bepassed into an equal number of program variables, just as with static statements.

    Varying-list SELECT statements can contain a variable number of columns. SQL can return information to your programabout the number and attributes of the columns used, but pointer references are required to access the information. Let

    me explain. With the number of columns of the SELECT statement being variable, your program must dynamicallyallocate memory at run time since the structure of a record is not known until then. Dynamically allocated memory cannotbe referenced by name; instead, it must be referenced by its memory address (pointer). By using a pointer, your programcan retrieve the data stored at the memory location you set up at run time. A whole article could easily be devoted to thevarying-list SELECT statement; but since RPG/400 cannot allocate memory dynamically or use pointers, our discussionis limited to fixed-list statements. But don't be discouraged-fixed-list statements are still very useful.

    Executing a dynamic SELECT statement when you want to gain access to one record at a time is very similar toexecuting a static statement. The steps are the same as those in 1 except for adding the PREPARE statement.

    Executing a dynamic SELECT statement when you want to gain access to one record at a time is very similar to

    executing a static statement. The steps are the same as those in Figure 1 except for adding the PREPARE statement.

    7 illustrates an RPG/400 program that will process a dynamic fixed-list SQL SELECT statement. The only restriction isthat all columns must be SELECTed (SELECT *). We are using a fixed list, but it includes all the columns. Here again, asin the static SQL example in 3, the physical file is used to create a data structure to FETCH INTO. Although the programSELECTs all columns, it does not have to use all columns.

    Figure 7 illustrates an RPG/400 program that will process a dynamic fixed-list SQL SELECT statement. The onlyrestriction is that all columns must be SELECTed (SELECT *). We are using a fixed list, but it includes all the columns.Here again, as in the static SQL example in Figure 3, the physical file is used to create a data structure to FETCH INTO.Although the program SELECTs all columns, it does not have to use all columns.

    The biggest advantage of this program is that the user can SELECT and order records in any way he can imagine. Youcan offer SELECTion and sorting abilities to everyone from the basic user all the way up to your most sophisticated userwithout ever having to say, "You can't do that or I'll have to make a program change." Depending on the skill of the user,you may create a prompted screen to help the user construct an SQL statement or simply present one long input fieldwhere the user can key free-form SQL statements.

    PREPARE/EXECUTE vs. EXECUTE IMMEDIATE

    In the dynamic SQL sample in 6, I used the PREPARE statement followed by an EXECUTE statement, even though I

    could have simply used EXECUTE IMMEDIATE. The advantage of using PREPARE followed by EXECUTE is that youcan use substitution values (parameter markers) within the dynamic statement. Parameter markers are indicated byplacing a question mark (?) in the SQL statement at the point where you want to substitute a value through a programvariable. For example, let's change the statement in 5 which represents a dynamic request and use a '?' in place of thedate constant (see 8). Now the same SQLRPG program used in 6, with a slight modification, can substitute a value forthe '?' used in the SQL statement. All I needed to do was add the "USING :program-variable" clause to the EXECUTEstatement (see 9). The value of the RPG/400 field INPDTE is substituted for the parameter marker. If more than oneparameter marker is used, separate the program variable name with a comma as 10 illustrates. You might use thisapproach whenever you want the system to determine a value instead of having the user specify it.

    In the dynamic SQL sample in Figure 6, I used the PREPARE statement followed by an EXECUTE statement, eventhough I could have simply used EXECUTE IMMEDIATE. The advantage of using PREPARE followed by EXECUTE isthat you can use substitution values (parameter markers) within the dynamic statement. Parameter markers are indicatedby placing a question mark (?) in the SQL statement at the point where you want to substitute a value through a programvariable. For example, let's change the statement in Figure 5 which represents a dynamic request and use a '?' in placeof the date constant (see Figure 8). Now the same SQLRPG program used in Figure 6, with a slight modification, cansubstitute a value for the '?' used in the SQL statement. All I needed to do was add the "USING :program-variable"

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    7/12

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    8/12

    Access Language (DAL) server for the AS/400 that allows Macintosh users to retrieve AS/400 data (see MC's October'92 Significa: "First AS/400 Fruit of the Apple Alliance"). Apple's DAL is an SQL-based data manipulation language.

    Anything you learn about SQL goes beyond the AS/400 and reaches into nearly every computer platform. With the ever-increasing importance of connectivity, incorporating SQL in your applications can place you in a better position forcommunicating with other machines and architectures. So start using embedded SQL in your applications. A few yearsfrom now, you'll be glad you made the move.

    References

    Systems Application Architecture Structured Query Language/400 Programmer's Guide (SC41-9609)

    Systems Application Architecture Structured Query Language/400 Reference (SC41-9608)

    Add Power to RPG/400 With Embedded SQLFigure 1 One-at-a-time record retrieval with SQL

    Figure 1: One-at-a-time Record Retrieval With SQL

    DECLARE cursor_name CURSOR FOR sql_statementOPEN cursor_nameFETCH cursor_name INTO program_variable/sCLOSE cursor_name

    Add Power to RPG/400 With Embedded SQLFigure 10 Dynamic SQL stmt with multiple program variable

    Figure 10: Dynamic SQL Statement With Multiple Program Variable

    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6

    EXECUTE SQLSTM USING :PGMVRI, :PGMVR2

    Add Power to RPG/400 With Embedded SQLFigure 2 Example of retrieving a record with embedded SQL

    Figure 2: Example of Retrieving a Record With Embedded SQL

    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6C/EXEC SQLC+ DECLARE REC_PTR CURSOR FORC+ SELECT CMNBR, CMNAME FROM CSTMSTC+ WHERE CMSTAT = 'A'C+ ORDER BY CMNAME

    C/END-EXEC*C/EXEC SQLC+ OPEN REC_PTRC/END-EXEC*C/EXEC SQLC+ FETCH REC_PTRC+ INTO :@CNBR, :@CNAMEC/END-EXEC*C/EXEC SQLC+ CLOSE REC_PTRC/END-EXEC... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6

    Add Power to RPG/400 With Embedded SQLFigure 3 Static SQL statements in RPG/400

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    9/12

    Figure 3: Static SQL Statements in RPG/400

    SQLCOD0: Record found

    by FETCH100: Record not

    found

    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6FLIST O E PRINTERIINREC E DSCSTMST*===========================================* Declare cursor for SQL statementC/EXEC SQLC+ DECLARE REC_PTR CURSOR FORC+ SELECT * FROM CSTMSTC+ WHERE CMADR1 LIKE :STRC+ ORDER BY CMNAMEC/END-EXEC*===========================================

    * Open cursorC/EXEC SQLC+ OPEN REC_PTRC/END-EXEC*===========================================* Loop until no more recordsC SQLCOD DOWEQ0* Load current record into data structure INRECC/EXEC SQLC+ FETCH REC_PTRC+ INTO :INRECC/END-EXECC SQLCOD IFNE 0

    C LEAVEC ENDIF*C WRITECMRECC ENDDO*===========================================* Close cursorC/EXEC SQLC+ CLOSE REC_PTRC/END-EXECC SETON LR*===========================================C *INZSR BEGSR

    C *ENTRY PLISTC PARM STR 10C ENDSR*===========================================... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6

    Add Power to RPG/400 With Embedded SQLFigure 4 SQL statements not allowed with dynamic execution

    Figure 4: SQL Statements Not Allowed or Limited With Dynamic Execution

    BEGIN DECLARE SECTIONCLOSECONNECT

    * DECLARE CURSORDECLARE STATEMENTDECLARE VARIABLE

    * DESCRIBE

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    10/12

    DESCRIBE TABLEEND DECLARE SECTION

    * EXECUTE* EXECUTE IMMEDIATE

    FETCHINCLUDEOPEN

    * PREPARE

    * SELECT INTO* SELECT-statement* WHENEVER

    * Limited usage: Refer to the Dynamic SQL chapter of the AS/400 SQL/400Programmer's Guide (SC41-9609)

    Add Power to RPG/400 With Embedded SQLFigure 5 User-submitted SQL statement

    Figure 5: User-submitted SQL Statement

    DELETE FROM CSTMEM WHERE CMDATE < 850101

    Add Power to RPG/400 With Embedded SQLFigure 6 Embedded non-SELECT dynamic SQL statement

    Figure 6: Embedded Non-SELECT Dynamic SQL Statement

    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6*===========================================* Prepare SQL statement from user inputC/EXEC SQLC+ PREPARE SQLSTM FROM :USRINPC/END-EXEC* Execute SQL statement

    C/EXEC SQLC+ EXECUTE SQLSTMC/END-EXEC*===========================================... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6

    Add Power to RPG/400 With Embedded SQLFigure 7 RPG/400 program with dynamic fixed-list SQL stmt

    Figure 7: RPG/400 Program With Dynamic Fixed-list SQL Statement

    SQLCOD0: Record found

    by FETCH100: Record not

    found

    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6IINREC E DSTESTFILE*===========================================*C EXSR EXC*===========================================C MOVE *ON *INLR*===========================================C EXC BEGSR*C/EXEC SQLC+ PREPARE SQLSTM FROM :USRINPC/END-EXEC*

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    11/12

    C SQLCOD IFGT 0* statement is not executableC CLEARUSRINPC MOVEL'*ERROR' USRINPC RETRNC ENDIF*C/EXEC SQL

    C+ DECLARE REC_PTR CURSOR FOR SQLSTMC/END-EXEC*C/EXEC SQLC+ OPEN REC_PTRC/END-EXEC**===========================================*C SQLCOD DOWEQ0*C/EXEC SQLC+ FETCH REC_PTR INTO :INREC

    C/END-EXEC*C SQLCOD IFNE 0C LEAVEC ENDIF*

    .(Process record)

    .*C ENDDO*C/EXEC SQL

    C+ CLOSE REC_PTRC/END-EXEC*C ENDSR*===========================================C *INZSR BEGSRC *ENTRY PLISTC PARM USRINP 80C ENDSR*===========================================

    Add Power to RPG/400 With Embedded SQLFigure 8 User-submitted SQL stmt with parameter marker

    Figure 8: User-submitted SQL Statement With Parameter Marker

    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6DELETE FROM CSTMEM WHERE CMDATE < ?

    Add Power to RPG/400 With Embedded SQLFigure 9 Dynamic SQL stmt with single program variable

    Figure 9: Dynamic SQL Statement With Single Program Variable

    ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6*===========================================* Execute SQL statementC/EXEC SQLC+ EXECUTE SQLSTM USING :INPDTEC/END-EXEC*===========================================

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

  • 7/27/2019 Add Power to RPG 400 With Embedded SQL

    12/12

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27