Sei sulla pagina 1di 12

MC Press Online

Add Power to RPG/400 With Embedded SQL


Contributed by Richard Shaler Saturday, 31 October 1992 Last 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 Terminology TABLE Physical File ROW Record COLUMN Field INDEX Logical File

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

Those of you using SQL know how easy it is to use for impromptu requests. SQL helps to reduce your programming backlog by allowing some end users to retrieve information on their own, and many programmers use it for quick updates to databases. Using a technique known as embedded SQL, you can extend the powerful data manipulation capabilities of 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 add records 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 your basic HLL database I/O. With a few brief SQL statements, you can accomplish what might otherwise take several programs 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 is to see it in action. Let's dissect a situation as it is handled with traditional programming techniques as compared to embedded SQL.

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

1. Create an interactive RPG/400 subfile program to present an alphabetic choose from.

listing of customer names for the user to

2. Pass the information created by the user's selections to an Open Query File of the customer information.

(OPNQRYF) command to create a view

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 the following logic:
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

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 in mind.

In order for an RPG/400 program to process SQL statements, you must designate the program source member as type SQLRPG and compile it with the Create SQL RPG Program (CRTSQLRPG) command. A precompiler analyzes and 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 the most recently executed SQL statement. If you look at your compile listing, you'll notice a data structure, SQLCA, which defines 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, if you need to read previous or read previous equal records, you will need to use RPG/400 I/O operations. Embedded SQL 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 SQL provides 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 your program. 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 are limited to RPG/400. Using SQL in the other languages is so similar that what is shown here can be easily applied to the other 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 16 must be blank. The SQL statement may start in position 17 and go through position 74 of this statement. The statement looks 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. The embedded SQL statement continuation line requires a 'C' in position 6, a '+' in position 7 and a blank in position 8. The SQL statement itself can be coded in mixed case between positions 9 and 74. It looks like this: ... 1 ...+... 2 ...+... 3 ...+... C+ SELECT * from Master
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

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 comment C+ SELECT * FROM CSTMST C+ 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 and normally requires several continuation lines. This is known as a static SQL statement because it is hard-coded. The only way 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 SELECT all records with a balance due that is greater than or equal to an amount a user has submitted to your program. The SQL statement would look like this: C/EXEC SQL C+ SELECT * FROM CSTMST C+ WHERE BALDUE >= :CMBAL C/END-EXEC

The RPG/400 program variable name CMBAL is preceded by a colon (:). The colon is used here much like the ampersand (&) in a CL program to indicate a variable. There is a field defined in the RPG/400 program called CMBAL that contains the value to be substituted in the SQL statement. In this case, CMBAL was defined in a display file that prompted 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. To solve it, we declare and use a record pointer in the program to access one record at a time from the set that SQL presents. SQL refers to this pointer as a cursor. There are four SQL statements related to cursor usage as illustrated in 1. The most important of these statements is the FETCH cursor INTO. It tells SQL to pass information into the program variable 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. To solve it, we declare and use a record pointer in the program to access one record at a time from the set that SQL presents. SQL refers to this pointer as a cursor. There are four SQL statements related to cursor usage as illustrated in Figure 1. The most important of these statements is the FETCH cursor INTO. It tells SQL to pass information into the program 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 the SQL statement to be executed. (The cursor name is an SQL identifier; therefore, we are able to use the underscore in the name.) Next, we open the cursor, FETCH the current record and place the columns CMNBR and CMNAME INTO the
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

program variables (RPG/400 fields) @CNBR and @CNAME. Here is an important rule to remember about the FETCH statement: You must FETCH INTO the same number of program variables as col-umns you selected in the SQL SELECT statement. In our example in 2, we are SELECTing two columns and FETCHing INTO two fields. If many fields are being used, you can simplify things by creating a data structure made up of the fields you will fetch INTO. Then you can 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 the underscore in the name.) Next, we open the cursor, FETCH the current record and place the columns CMNBR and CMNAME INTO the program variables (RPG/400 fields) @CNBR and @CNAME. Here is an important rule to remember about the FETCH statement: You must FETCH INTO the same number of program variables as col-umns you selected in the SQL SELECT statement. In our example in Figure 2, we are SELECTing two columns and FETCHing INTO two fields. If many fields are being used, you can simplify things by creating a data structure made up of the fields you will fetch 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 structure 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 all the fields for the record format of file CSTMST, resulting in an equal number of columns and program variables. The FETCH is contained 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 data structure 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 data structure 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 all the fields for the record format of file CSTMST, resulting in an equal number of columns and program variables. The FETCH is contained 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 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 a customer address that contains the string submitted by the user. We simply use the SQL LIKE predicate (a predicate expresses a comparison) and pass the character string to be searched for, using program variable STR. If you're not familiar with LIKE, check it out. It's very useful for flexible searches. Notice that the four SQL statements shown in 1 are used in the program. The program in 3 could be used by a typical subfile program to display records that match a usersubmitted pattern. Since RPG/400 is not reading the customer master file, it has no F-spec for it. Input is handled by SQL.

This program accepts a character string through an entry parameter and accesses every customer record with a customer address that contains the string submitted by the user. We simply use the SQL LIKE predicate (a predicate expresses a comparison) and pass the character string to be searched for, using program variable STR. If you're not familiar with LIKE, check it out. It's very useful for flexible searches. Notice that the four SQL statements shown in Figure 1 are used in the program. The program in Figure 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
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

handled by SQL.

Dynamic Embedded SQL

Embedded SQL can also be dynamic, which means that the SQL statement is submitted and prepared at run time instead 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 to analyze and interpret what the user keyed to determine if the statement is valid. Because it is created on the fly, dynamic SQL imposes some limitations on the SQL statements that can be used. 4 lists the SQL statements that are not valid 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:

Embedded SQL can also be dynamic, which means that the SQL statement is submitted and prepared at run time instead 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 to analyze and interpret what the user keyed to determine if the statement is valid. Because it is created on the fly, dynamic SQL imposes some limitations on the SQL statements that can be used. Figure 4 lists the SQL statements that are not valid 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 statement and then execute it with the EXECUTE statement, or 2) Prepare and execute it with the EXECUTE IMMEDIATE statement.

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

Dynamic SQL statements are divided into two types: SELECT statements and non- SELECT statements. Examples of non-SELECT statements include INSERT, DELETE and UPDATE. We'll look at the non-SELECT statements first by examining 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, which is referenced in the PREPARE statement, as illustrated in 6. The program could just as easily execute other SQL statements such as INSERT, UPDATE, CREATE TABLE or CREATE INDEX.

Dynamic SQL statements are divided into two types: SELECT statements and non- SELECT statements. Examples of non-SELECT statements include INSERT, DELETE and UPDATE. We'll look at the non-SELECT statements first by examining 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 other SQL statements such as INSERT, UPDATE, CREATE TABLE or CREATE INDEX.

Dynamic SELECT Statements


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

MC Press Online

Dynamic SELECT statements fall into two categories: fixed-list and varying- list. Fixed-list statements are those that retrieve a predictable number and type of columns. They must always contain a set number of columns which must be passed 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 program about 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 dynamically allocate memory at run time since the structure of a record is not known until then. Dynamically allocated memory cannot be referenced by name; instead, it must be referenced by its memory address (pointer). By using a pointer, your program can retrieve the data stored at the memory location you set up at run time. A whole article could easily be devoted to the varying-list SELECT statement; but since RPG/400 cannot allocate memory dynamically or use pointers, our discussion is 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 to executing 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 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 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.

Figure 7 illustrates an RPG/400 program that will process a dynamic fixed-list SQL SELECT statement. The only restriction 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. You can offer SELECTion and sorting abilities to everyone from the basic user all the way up to your most sophisticated user without 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 field where 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 you can use substitution values (parameter markers) within the dynamic statement. Parameter markers are indicated by placing a question mark (?) in the SQL statement at the point where you want to substitute a value through a program variable. For example, let's change the statement in 5 which represents a dynamic request and use a '?' in place of the date constant (see 8). Now the same SQLRPG program used in 6, with a slight modification, can substitute a value for the '?' used in the SQL statement. All I needed to do was add the "USING :program-variable" clause to the EXECUTE statement (see 9). The value of the RPG/400 field INPDTE is substituted for the parameter marker. If more than one parameter marker is used, separate the program variable name with a comma as 10 illustrates. You might use this approach 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, even though I could have simply used EXECUTE IMMEDIATE. The advantage of using PREPARE followed by EXECUTE is that you can use substitution values (parameter markers) within the dynamic statement. Parameter markers are indicated by placing a question mark (?) in the SQL statement at the point where you want to substitute a value through a program variable. For example, let's change the statement in Figure 5 which represents a dynamic request and use a '?' in place of the date constant (see Figure 8). Now the same SQLRPG program used in Figure 6, with a slight modification, can substitute a value for the '?' used in the SQL statement. All I needed to do was add the "USING :program-variable"
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

clause to the EXECUTE statement (see Figure 9). The value of the RPG/400 field INPDTE is substituted for the parameter marker. If more than one parameter marker is used, separate the program variable name with a comma as Figure 10 illustrates. You might use this approach whenever you want the system to determine a value instead of having the user specify it.

Editing and Compiling an SQLRPG Program

Now that you have an idea what embedded SQL looks like and how to incorporate it into your RPG programs, all that remains is editing your source member and creating an executable program.

SEU will not choke on embedded SQL statements when the member type is SQLRPG. In fact, SEU will perform some basic syntax checking of the SQL statements (have you used valid SQL keywords, are the keywords in the correct order, and so forth). Of course, it won't check things like whether the file you specified is on the system or that a field name is valid. For complete SQL statement syntax checking, here's a technique you might consider using.

1. Start interactive SQL (STRSQL), key the SQL statement and execute it against a test version of your file. Using a test version is very important when the statement modifies your database. Even if you're only using the SELECT statement, test files are a good idea since they usually contain less data than your live files. There's no need to wait for 100,000 records to be processed to check the syntax of a statement.

2. When you end the SQL session, use option 4 ('Save session in source file'). Save the session to a source file of your choosing and give the member a name you can remember, or simply use the name of the RPG/400 program you want to create.

3. Create your SQLRPG program and include the source code from the saved SQL program name for the saved session, just edit this source member.

session. If you used your SQLRPG

You now know the SQL statements you have embedded will work.

The CRTSQLRPG command will compile SQLRPG source members. Be aware that the COMMIT parameter defaults to *CHG. Unless you are journaling your files, you will want to change the COMMIT parameter to a value of *NONE; using *CHG requires journaling to be active. If you don't use journaling, you can create your own version of CRTSQLRPG in a library higher than QSYS in the library list and change the default value of the COMMIT parameter to *NONE.

If any of the SQL statements are in error during precompile, you get an additional listing indicating the problem with the statement. An interesting little quirk here is that the compiler creates a program even though there are errors in the SQL statements. Your compile listing contains the RPG/400 operations generated from the SQL statements by the precompiler.

Exploit Embedded SQL

Consider embedded SQL as another tool you can easily incorporate into your code to give you the ability to get things done faster and more efficiently. As the recognized standard Data Manipulation Language (DML) for relational databases, SQL can be found on most any operating system on the market today. It's difficult to mention relational database without also talking about SQL.

Although it has its limitations and is not a panacea for all your file I/O, it can work very well for many applications. In some ways it is the most advanced language we have available on the AS/400. For instance, as of V2R1M1, SQL is the only language that supports four significant new data types (Null-capable, Date, Time and Timestamp).

IBM is very committed to SQL on the AS/400 and is constantly adding performance improvements to SQL. It is used extensively in IBM and non-IBM multi-platform integration software. Just recently, Apple Computer announced a Data
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

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 everincreasing importance of connectivity, incorporating SQL in your applications can place you in a better position for communicating with other machines and architectures. So start using embedded SQL in your applications. A few years from 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 SQL Figure 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_statement OPEN cursor_name FETCH cursor_name INTO program_variable/s CLOSE cursor_name Add Power to RPG/400 With Embedded SQL Figure 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 SQL Figure 2 Example of retrieving a record with embedded SQL Figure 2: Example of Retrieving a Record With Embedded SQL ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 C/EXEC SQL C+ DECLARE REC_PTR CURSOR FOR C+ SELECT CMNBR, CMNAME FROM CSTMST C+ WHERE CMSTAT = 'A' C+ ORDER BY CMNAME C/END-EXEC * C/EXEC SQL C+ OPEN REC_PTR C/END-EXEC * C/EXEC SQL C+ FETCH REC_PTR C+ INTO :@CNBR, :@CNAME C/END-EXEC * C/EXEC SQL C+ CLOSE REC_PTR C/END-EXEC ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 Add Power to RPG/400 With Embedded SQL Figure 3 Static SQL statements in RPG/400
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

Figure 3: Static SQL Statements in RPG/400 SQLCOD 0: Record found by FETCH 100: Record not found ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 FLIST O E PRINTER IINREC E DSCSTMST *=========================================== * Declare cursor for SQL statement C/EXEC SQL C+ DECLARE REC_PTR CURSOR FOR C+ SELECT * FROM CSTMST C+ WHERE CMADR1 LIKE :STR C+ ORDER BY CMNAME C/END-EXEC *=========================================== * Open cursor C/EXEC SQL C+ OPEN REC_PTR C/END-EXEC *=========================================== * Loop until no more records C SQLCOD DOWEQ0 * Load current record into data structure INREC C/EXEC SQL C+ FETCH REC_PTR C+ INTO :INREC C/END-EXEC C SQLCOD IFNE 0 C LEAVE C ENDIF * C WRITECMREC C ENDDO *=========================================== * Close cursor C/EXEC SQL C+ CLOSE REC_PTR C/END-EXEC C SETON LR *=========================================== C *INZSR BEGSR C *ENTRY PLIST C PARM STR 10 C ENDSR *=========================================== ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 Add Power to RPG/400 With Embedded SQL Figure 4 SQL statements not allowed with dynamic execution Figure 4: SQL Statements Not Allowed or Limited With Dynamic Execution BEGIN DECLARE SECTION CLOSE CONNECT * DECLARE CURSOR DECLARE STATEMENT DECLARE VARIABLE * DESCRIBE
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

DESCRIBE TABLE END DECLARE SECTION * EXECUTE * EXECUTE IMMEDIATE FETCH INCLUDE OPEN * PREPARE * SELECT INTO * SELECT-statement * WHENEVER * Limited usage: Refer to the Dynamic SQL chapter of the AS/400 SQL/400 Programmer's Guide (SC41-9609) Add Power to RPG/400 With Embedded SQL Figure 5 User-submitted SQL statement Figure 5: User-submitted SQL Statement DELETE FROM CSTMEM WHERE CMDATE < 850101 Add Power to RPG/400 With Embedded SQL Figure 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 input C/EXEC SQL C+ PREPARE SQLSTM FROM :USRINP C/END-EXEC * Execute SQL statement C/EXEC SQL C+ EXECUTE SQLSTM C/END-EXEC *=========================================== ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 Add Power to RPG/400 With Embedded SQL Figure 7 RPG/400 program with dynamic fixed-list SQL stmt Figure 7: RPG/400 Program With Dynamic Fixed-list SQL Statement SQLCOD 0: Record found by FETCH 100: Record not found ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 IINREC E DSTESTFILE *=========================================== * C EXSR EXC *=========================================== C MOVE *ON *INLR *=========================================== C EXC BEGSR * C/EXEC SQL C+ PREPARE SQLSTM FROM :USRINP C/END-EXEC *
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

C SQLCOD IFGT 0 * statement is not executable C CLEARUSRINP C MOVEL'*ERROR' USRINP C RETRN C ENDIF * C/EXEC SQL C+ DECLARE REC_PTR CURSOR FOR SQLSTM C/END-EXEC * C/EXEC SQL C+ OPEN REC_PTR C/END-EXEC * *=========================================== * C SQLCOD DOWEQ0 * C/EXEC SQL C+ FETCH REC_PTR INTO :INREC C/END-EXEC * C SQLCOD IFNE 0 C LEAVE C ENDIF * . (Process record) . * C ENDDO * C/EXEC SQL C+ CLOSE REC_PTR C/END-EXEC * C ENDSR *=========================================== C *INZSR BEGSR C *ENTRY PLIST C PARM USRINP 80 C ENDSR *=========================================== Add Power to RPG/400 With Embedded SQL Figure 8 User-submitted SQL stmt with parameter marker Figure 8: User-submitted SQL Statement With Parameter Marker ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 DELETE FROM CSTMEM WHERE CMDATE < ? Add Power to RPG/400 With Embedded SQL Figure 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 statement C/EXEC SQL C+ EXECUTE SQLSTM USING :INPDTE C/END-EXEC *===========================================
http://www.mcpressonline.com Powered by Joomla! Generated: 19 September, 2008, 00:27

MC Press Online

http://www.mcpressonline.com

Powered by Joomla!

Generated: 19 September, 2008, 00:27

Potrebbero piacerti anche