Rabu, 03 April 2013

AS/400 Chapter 6: RPG

RPG is one of the AS400 platform pillars. Originally designed as a query tool it has been substantially enlarged, it is currently a very powerful language. Let's see how you can use it.
RPG is a programming language best suited for business applications. Originally the acronym meant Report Program Generator, but currently it has no officially meaning. For the purpose of this tutorial we will use the latest RPG version: RPG IV.
RPG, like DDS, is a positional language despite its last version allowing a free format where you can place the code in mostly any column or line.
In the RPG code there are several different types of specifications. Each has a different function and they all appear in the file in a specific order. The letter that represents the specification must be placed in the initial position of the source code line. Next we have a description of each specification in the order they appear in a file.

H Specification (header)

Compile/execution options.

F Specification (file)

Files definition and how they are used in the program. Options in an F specification (for more info on any option place the cursor on it and press F1):
F Specification

D Specification (definition)

Here you can define variables and data structures, for instance:
D Specification

C Specification

Here you define the source code. There is a free format for this specification but to do so instead of placing a C at the beginning of a line you should place free in the beginning of the code block and end-free in the end. These keywords must start in the the second position from the beginning of the line (in SEU).


Basic RPG Syntax

Valid operators

= (compare and attribute), +, -, *, /, >, >=, <, <=, <>, NOT, AND, OR

Conditional Expressions

if condition;
    //code
else;
    if other-condition;
        ...
    endif;
endif;

Do-while cycle

doW condition;
    //code
endDo;

Creating and defining an RPG member

In this chapter you're going to create a program that shows the number of cards the client with ID 1 has.
You must first insert some records in the CARDS table associated with client 1. Do this from STRSQL.
Create the source file DEMO/QRPGLESRC. Inside this source file create a member named COUNTCARDS. The member type must be SQLRPGLE.
Since we're not going to explicitly open any file, there won't be any lines with F specification.
You must define a variable (count) that will store the number of cards from the client. Place the letter “D” in the first column of the SEU editor and press F4. This variable will be simple (place an “s” in the Declaration Type), numeric, with length 5 and 0 decimal places. Initiate the variable to zero with the function INZ(initial-value) in the Keywords field. Were you able to declare the variable with the F4 prompt help? If not, check the final result further ahead.
Try to create the code for the next three points. Keep in mind that in the free format RPG you can write your code in whatever column you like (but it must at least start in column 3 in the SEU) and that each code line must end with a semi column (;).
  • Initiate (/free) and finalize (/end-free) the code block in separate lines, starting from the second column in SEU.
  • Print the value of the count variable. To print values on the screen you can use the dsply function. Dsply syntax: dsply value.
  • In the last line, before /end-free, you must activate the end of code indicator *inlr (in last row). You activate it like this: *inlr = *on;
If you completed the three points and declared the variable you should have something like this:
* this is a comment
* variable definition
Dcount s 5P 0 INZ(0)
  
/free
    dsply count;       * displays the count value on the screen
    *inlr = *on;       * tells the compiler that this is the last line.
/end-free
Try to compile the source code now (option 14 of PDM). If the compilation was successful execute the program typing the following line in the system prompt: call DEMO/COUNTCARDS
The following information should appear:
dsply 0
A list of values may appear (from previous events), but the one from the current execution is the last one on the list. For instance if you call the COUNTCARDS twice on the list you'll see:
dsply 0
dsply 0
We still need to count the number of cards client 1 has.

Embedded SQL and Subroutines

To view and alter tables we can use SQL code embedded in RPG code (RPG provides a way to manipulate tables, but since you should already know SQL we'll use it instead).
This is how we embed SQL in RPG:
c/EXEC SQL
c+ SQL-instruction
c/END-EXEC
In each EXEC block you can only have one SQL statement. We will see a better example of this in the next chapter.
So, to retrieve the number of cards we can do this query (write this code at the end of the source code, after the end-free):
c/EXEC SQL
c+ SELECT COUNT(*) INTO :count FROM DEMO/CARDS
c+ WHERE CLIENT_CRD = 1
c/END-EXEC
To better organize your code we will place this EXEC block in a subroutine. A subroutine is kind of like a function but it doesn't allow parameter passing or returning values although you can change globally defined variables. Inside a subroutine you can have free-format RPG, fixed-format RPG or EXEC instructions.
The EXEC block you just created should be placed in a subroutine called getNrCards. This is how you do it (you can use the F4 prompt to place the keywords correctly):
c getNrCards begsr
c/EXEC SQL
c+ SELECT COUNT(*) INTO :count FROM DEMO/CARDS
c+ WHERE CLIENT_CRD = 1
c endsr
To run the subroutine you must call it in the main /free block. Place this line before displaying the count variable.
exSr getNrCards; *execute sub-routine getNrCards
Compile and run the code again. Did you get the same result? If so, check to see if client 1 exists and that there are cards associated with him. And, of course, the tutorial must be correctly completed until this point. If even that doesn't work compare your code with this one:
Dcount s 5P 0 INZ(0)
 *------------------------------------------------*
 /free
     exSr getNrCards;
     dsply count;
     *inlr = *on;
 /end-free
 *------------------------------------------------*
c getNrCards begsr
c/EXEC SQL
c+ SELECT COUNT(*) INTO :count FROM DEMO/CARDS
c+ WHERE CLIENT_CRD = 1
c/END-EXEC
c endsr

Tidak ada komentar:

Posting Komentar