SQL for RPG Programmers

Get your copy of this important training now:
http://www.Lab400.com/product_detail.asp?prod_id=204

A sample chapter from Daniel Jacobs training SQL for RPG Programmers follows.

Chapter 2 Getting started: using the SQL INSERT statement
In this chapter you will learn how to insert a row of data into a database table using embedded SQL in an RPG program. Just to start things off with a bang, the embedded SQL statements are in a program that uses an OS/400 system API with pointer variables.

2.1 Chapter goals
You will complete the following tasks in this chapter:
• • • • • • • •

Learn some basic SQL terminology. Learn the syntax of the SQL statement compiler directive. Create a collection and table. Work with a simple SQL INSERT statement. Use host variables in the embedded SQL. Use the list objects system API with pointers. Compile ILE RPG modules and programs using embedded SQL. Complete a lab using an embedded SQL INSERT statement.

2.2 Some basic SQL terminology
In standard SQL you will hear about schemas. However, on the AS/400, all elements of an SQL database are created in an SQL collection. In many ways, OS/400 treats a collection exactly as it treats a library object. In fact, if you create a collection named RPG_SQLFOO you can use the command WRKLIB RPG_SQLFOO just as if you had created RPG_SQLFOO with the CRTLIB command. There are some important differences between a collection and a library. DB2 automatically creates several system tables in the new collection, in addition to a journal and a journal receiver. You will see all of that soon. Notice in the previous paragraph I said system tables, not system files. In the SQL universe
• • •

Files are called tables Records are called rows Fields are called columns

Thus, you have column names, not field names. You can access existing physical files, their records and fields using SQL. Just call them tables and rows and columns. Also, in a lot of AS/400 shops the term file pointer is used. A file pointer is some mysterious thing that presumably points to a particular record in an open data path. There are no file pointers in SQL. There are SQL cursors instead, which you will use in later chapters. There will probably be some more words to learn as you go along, but that is enough to get started.

Getting started: using the SQL INSERT statement

7

2.3 The SQL compiler directive in RPG
It's quite simple. To use SQL in an RPG program, you use a compiler directive for SQL statements in the C–specs. This is an example of a compiler directive enclosing an SQL statement:
C/EXEC SQL C+ C/END-EXEC DROP TABLE RPG_SQL/OBJINF

The C/EXEC SQL and C/END-EXEC directives tell the RPG compiler that the lines between will be compiled by the SQL pre–compiler and executed at run time by the DB2 engine. The statement in between (DROP TABLE) can be any SQL statement that is allowed in the embedded RPG environment. You can have as many C+ lines as you need between the C/EXEC SQL and C/END-EXEC directives to complete your SQL statement. You can put only one SQL statement in an EXEC SQL and END-EXEC pair. However, you can use as many EXEC SQL and END-EXEC pairs as needed in your program, so you can have multiple embedded SQL statements in a program.

2.4 Create an SQL collection
Note: your user profile must be authorized to create a library to run the steps in this section. ____ Enter the following command on an AS/400 command line to start the interactive SQL environment:
STRSQL

____ Enter the following SQL command at the SQL command line
CREATE COLLECTION RPG_SQLFOO

Note: you can enter SQL commands in upper or lower case. ____ Now go to an AS/400 command line and enter the command
WRKLIB RPG_SQLFOO

____ Enter option 12 (Work with objects) for the RPG_SQLFOO library to display the objects. ____ You should see a display similar to Figure 2. When you create a collection, SQL automatically adds the journal receiver, journal and system tables shown in the figure.

8

Getting started: using the SQL INSERT statement

020005

Figure 2: The Work with Objects display for the RPG_SQLFOO library (collection).

____ Just for fun, start the SQL environment again (STRSQL) and enter the following SELECT statement for one of the tables in the collection:
SELECT * FROM RPG_SQLFOO/SYSCOLUMNS

Note: Before running the SELECT, you may want to press F13 from your SQL session screen, take option 1 from the menu and make sure that the second parameter (SELECT output) is set to 1. ____ You should see a screen of data, as shown in Figure 3.

Getting started: using the SQL INSERT statement

9

020010

Figure 3: The output of the SELECT statement over the SYSCOLUMNS table.

Can you guess what is going on? Figure 2 shows the objects that were created when you ran the CREATE COLLECTION command. Along with the library named RPG_SQLFOO, the SQL engine created a journal and a journal receiver. Because commitment control (also referred to as transaction processing) is a standard part of the DB2 SQL implementation, the journal was created automatically. When you create a table in RPG_SQLFOO, you will see that it is automatically journalled to the RPG_SQLFOO journal. In addition to journal QSQJRN and its attached receiver, there are a several logical files. Those are actually SQL views. DB2 stores information about every database object in a set of tables that make up the catalog. There are tables to keep track of table names, indices, views, triggers, constraints — in short, everything that can be created in SQL. In Figure 3, you see the column names that exist in every table in the RPG_SQLFOO Collection. Since you have not yet created any tables of your own, the column names belong to the catalog tables themselves.

10

Getting started: using the SQL INSERT statement

2.5 Create an SQL table
____ If you are not in an interactive SQL session, use the STRSQL command to start SQL. Enter the following SQL command:
CREATE TABLE RPG_SQLFOO/TFOO (TCOL1 CHAR (5), TCOL2 DEC (5,2) NOT NULL WITH DEFAULT, PRIMARY KEY (TCOL1))

____ You have just created an SQL table named TFOO in collection RPG_SQLFOO. The table has two columns, TCOL1 and TCOL2. TCOL1 is character length 5, and TCOL2 is decimal with two decimal places. TCOL2 cannot be null; if a row is created in TFOO without specifying the value of TCOL2 it will receive a default value of 0. ____ Enter the following command to view the SQL catalog view of the columns in the TFOO table:
SELECT * FROM RPG_SQLFOO/SYSCOLUMNS WHERE TABLE_NAME = 'TFOO'

____ You should see a list of column names as shown in Figure 4:

020015

Figure 4: The SYSCOLUMNS table contains the names of the columns in the TFOO table.

The CREATE statement also allows for referential and check constraints. You will learn about constraints later in this manual.

Getting started: using the SQL INSERT statement

11

2.6 Use the SQL INSERT statement
Now that you have a table, you can put something into it. ____ Enter the following SQL statement in the SQL session:
INSERT INTO RPG_SQLFOO/TFOO VALUES('FOOEY', 100.02)

____ Enter the following SQL statement to view the results of the INSERT statement:
SELECT * FROM RPG_SQLFOO/TFOO

You should see your newly entered data, as shown in Figure 5.

020020

Figure 5: The SELECT statement displays the data that was added with the INSERT statement.

____ In a later chapter you will learn how to populate multiple rows in one table from one or more other tables with a single INSERT statement.

12

Getting started: using the SQL INSERT statement

2.7 Using host variables
All this is fine and well, but if you are going to use SQL inside a program you need some way to use host variables in an SQL statement. By using host variables, you can use the INSERT statement for different data values, for example, for values that you get from a display file format. It is actually quite simple to use host variables in RPG. Suppose the previous INSERT statement was part of a program. Now suppose there are program variables @Tcol1 and @Tcol2 that are defined like TCOL1 and TCOL2 in table TFOO. Currently, those program variables (called host variables in SQL) hold the values FOOEY and 100.02. To insert those values into table TFOO you can use the following embedded SQL statement:
C/EXEC SQL C+ C+ C+ C/END-EXEC INSERT INTO RPG_SQLFOO/TFOO VALUES( :@TCol1, :@TCol2 )

Notice the colon before the variable names. The colons inform the SQL compiler that the values are host variables. Now let's put everything together and use embedded SQL in a useful RPG program.

Getting started: using the SQL INSERT statement

13

2.8 Lab 2–1 — Use an INSERT statement and the List Objects API
Strictly speaking this book is not about OS/400 system APIs, nor about ILE RPG pointers. If those tools are not yet part of your toolset, you can still learn embedded SQL. A word of advice, however: system APIs and ILE RPG pointers should be a standard part of an advanced programmer’s toolset. So give it a shot! In this section you’ll work with an RPG program that uses embedded SQL and the List Objects system API. The program lists objects from a library name passed to it into a user space. It then loops through the list of objects in the user space and uses the SQL INSERT statement to insert some of the information retrieved by the API into an SQL table. For example, Figure 6 shows a sample of the data inserted into the table when the program is run to get the contents of the RPG_SQL library.

020025

Figure 6: The output of the POBJLIST program is data about objects in a library, inserted into the table with an SQL INSERT statement.

I adapted some code in this example from the excellent book iSeries & AS/400 APIs at Work by Doug Pence & Ron Hawkins1.

1

This book is available from Rochester Initiative (http://www.lab400.com) and Midrange Computing (http://www.mc-store.com). 14 Getting started: using the SQL INSERT statement

2.8.1 Source members used in this lab
Source member Type Description

RPG_SQL/QRPGLESRC(CRTUSRSPC)

RPGLE

RPG module that contains procedure CrtUsrSpc to create a user space. RPG program that creates a user space, uses the List Objects API to write library objects to it, retrieves user space entries and uses an embedded SQL INSERT statement to enter data into a table.

RPG_SQL/QRPGLESRC(POBJLIST)

RPGLE

2.8.2 Create the CRTUSRSPC module
____ Use your source code editor (SEU, CODE/400 or another editor) to open and review source member RPG_SQL/QRPGLESRC(CRTUSRSPC).
H NOMAIN **************************************************************** * Procedure prototype **************************************************************** D CrtUsrSpc PR * D UsrSpc 20 const

**************************************************************** * Procedure CrtUsrSpc **************************************************************** P CrtUsrSpc B export D D CrtUsrSpc UsrSpc PI 20 * const

**************************************************************** * Local Variables **************************************************************** D UsrSpcAttr S 10 inz('LISTOBJ') D UsrSpcAuth S 10 inz('*CHANGE') D UsrSpcLen S 10I 0 inz(2048) D UsrSpcName S like(UsrSpc) D UsrSpcReplc S 10 inz('*YES') D UsrSpcText S 50 inz('For ListObjects API') D UsrSpcValue S 1 inz(x'00') D ErrorDs D BytesProvd D BytesAvail D MessageId D EReserved D EData DS 10I 0 inz(%len(EData)) 10I 0 inz(0) 7 1 40

(continues)

Getting started: using the SQL INSERT statement

15

D ChgAttrDs D NumberAttr D KeyAttr D DataSize D AttrData D ListPtr D Slib

DS 10I 0 inz(1) 10I 0 inz(3) 10I 0 inz(1) 1 inz('1') S S * 10

**************************************************************** * Set user space name to a variable for use on API calls. * Parms passed to APIs must be variables that can be modified. * UsrSpc is passed as "const" and cannot be modified. **************************************************************** C eval UsrSpcName = UsrSpc

**************************************************************** * Create the user space **************************************************************** C C C C C C C C C Call Parm Parm Parm Parm Parm Parm Parm Parm 'QUSCRTUS' UsrSpcName UsrSpcAttr UsrSpcLen UsrSpcValue UsrSpcAuth UsrSpcText UsrSpcReplc ErrorDs

**************************************************************** * Change user space to be extendable **************************************************************** C C C C C Call Parm Parm Parm Parm 'QUSCUSAT' Slib UsrSpcName ChgAttrDs ErrorDs

**************************************************************** * Get pointer to user space **************************************************************** C C C C P CrtUsrSpc E Call Parm Parm Return 'QUSPTRUS' UsrSpcName ListPtr ListPtr

____ Use the following command to create the CRTUSRSPC module:
CRTRPGMOD MODULE(RPG_SQL/CRTUSRSPC) SRCFILE(RPG_SQL/CRTUSRSPC) DBGVIEW(*ALL)

16

Getting started: using the SQL INSERT statement

2.8.3 Review the CRTUSRSPC module
The CRTUSRSPC module contains one procedure: CrtUsrSpc. When you call the procedure, you pass it the name of the user space to create and its library in a single character string. The value is passed as a const parameter, meaning that it is passed by reference and cannot be modified in the procedure. The procedure calls three system APIs:
• •

QCUSCRTUS — create the user space with the specified attributes QUSCUSAT — change the user space attributes so that the user space is

extendable

QUSPTRUS — get a pointer to the user space

Create the user space The QUSCRTUS API is used to create the user space. The user space is created with an initial length of 2048 bytes, initialized to the hexadecimal value x'00' (null character). Change user space attributes The QUSCUSAT API changes an attribute of the user space so it will be extendable. If the amount of data written to the user space is greater than 2048 bytes, the user space will be automatically extended. Get a pointer to the user space The QUSPTRUS API gets a pointer to the user space. The pointer points to the first byte in the user space. The pointer is returned to the caller of procedure.

Getting started: using the SQL INSERT statement

17

2.8.4 Create the POBJLIST module
____ Use your source code editor to open and review source member RPG_SQL/QRPGLESRC(POBJLIST).
**************************************************************** * Procedure prototype **************************************************************** D CrtUsrSpc PR * D UsrSpcName 20 const **************************************************************** * Work fields and constants **************************************************************** D InLib S 10 D ListFormat S 8 inz('OBJL0300') D ObjNamLib S 20 D ObjType S 10 inz(ALL) D ALL D USRSPC_NAME D USRSPC_LIB D UserSpace D SpaceName D SpaceLib C C C DS 10 10 overlay(UserSpace) overlay(UserSpace : *NEXT) '*ALL 'POBJLIST 'QTEMP ' ' '

**************************************************************** * General Header Data structure as copied from QUSGEN in * source file QSYSINC/QRPGLESRC **************************************************************** DQUSH0300 D* D QUSUA00 D* D QUSSGH00 D* D QUSSRL00 D* D QUSFN00 D* D QUSAU00 D* D QUSDTC00 D* D QUSIS00 D* D QUSSUS00 D* D QUSOIP00 D* DS 1 65 69 73 81 91 104 105 109 64 User Area 68B 0 Size Generic Header 72 Structure Release L 80 Format Name 90 Api Used 103 Date Time Created 104 Information Status 108B 0 Size User Space 112B 0 Offset Input Parame Based(GenHeaderPtr) Qus Generic Header

18

Getting started: using the SQL INSERT statement

D QUSSIP00 D* D QUSOHS00 D* D QUSSHS00 D* D QUSOLD00 D* D QUSSLD00 D* D QUSNBRLE00 D* D QUSSEE00 D* D QUSSIDLE00 D* D QUSCID00 D* D QUSLID00 D* D QUSSLI00 D* D QUSRSV1 D* D QUSEPN D* D QUSRSV2 D*

113 117 121 125 129 133 137 141 145 147 150 151 193 449

116B 0 Size Input Paramete 120B 0 Offset Header Secti 124B 0 Size Header Section 128B 0 Offset List Data 132B 0 Size List Data 136B 0 Number List Entries 140B 0 Size Each Entry 144B 0 CCSID List Ent 146 Country ID 149 Language ID 150 Subset List Indicat 192 Reserved 1 448 Entry Point Name 576 Reserved 2

***************************************************************** * Type Definition for the OBJL0300 format ***************************************************************** DQUSL030000 DS Based(ListPtr) D* Qus OBJL0300 D QUSOBJNU01 1 10 D* Object Name Used D QUSOLNU01 11 20 D* Object Lib Name Used D QUSOBJTU01 21 30 D* Object Type Used D QUSIS02 31 31 D* Information Status D QUSEOA00 32 41 D* Extended Obj Attr D QUSTD07 42 91 D* Text Description D QUSUDA00 92 101 D* User Defined Attr D QUSERVED23 102 108 D* Reserved D QUSASP 109 112B 0 D* Aux Storage Pool D QUSOBJO 113 122 D* Object Owner D QUSOBJD 123 124 D* Object Domain

(continues)

Getting started: using the SQL INSERT statement

19

D QUSCDT00 D* D QUSCDT01 D* D QUSORAGE D* D QUSOBJCS D* D QUSAC D* D QUSCBPGM D* D QUSOBJAV D* D QUSRSV207

125 133 141 151 152 153 154 164

132 Create Date Time 140 Change Date Time 150 Storage 151 Object Compress Status 152 Allow Change 153 Changed By Program 163 Object Audit Value 172

***************************************************************** * Main processing ***************************************************************** C C C C* C C C* C* C C C C C C C *entry plist parm exsr Setup

InLib

Load the list data structure eval do ListPtr = GenHeaderPtr + QUSOLD00 QUSNBRLE00

Process if the list entry has no problems, otherwise ignore it if exsr endif eval enddo eval return QUSIS02 = *blanks InsObjInf

ListPtr = ListPtr + QUSSEE00

*inlr = *on

20

Getting started: using the SQL INSERT statement

***************************************************************** * Insert object information in SQL table ***************************************************************** C InsObjInf begsr

C/EXEC SQL C+ C+ C+ C+ C+ C+ C+ C/END-EXEC C

INSERT INTO RPG_SQL/OBJINF VALUES ( :QUSOBJNU01, :QUSOLNU01, :QUSOBJTU01, :QUSOBJO, :QUSASP, :QUSORAGE )

endsr ***************************************************************** * Create the table, create the user space *****************************************************************

C

Setup

begsr

C/EXEC SQL C+ C/END-EXEC C/EXEC SQL C+ C+ C+ C+ C+ C+ C+ C/END-EXEC

DROP

TABLE RPG_SQL/OBJINF

CREATE TABLE RPG_SQL/OBJINF (OBJNAM CHARACTER (10 ) NOT OBJLIB CHARACTER (10 ) NOT OBJTYP CHARACTER (10 ) NOT OBJOWN CHARACTER (10 ) NOT OBJSTGPL NUMERIC (5,0) NOT OBJSTG CHARACTER (10 ) NOT

NULL NULL NULL NULL NULL NULL

WITH WITH WITH WITH WITH WITH

DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)

C* create user space for file list information C C C eval eval eval SpaceName SpaceLib = USRSPC_NAME = USRSPC_LIB

GenHeaderPtr = CrtUsrSpc(UserSpace)

C* list objects to user space C C C C C C C** don't include C eval call parm parm parm parm parm endsr ObjNamLib = ALL + InLib 'QUSLOBJ' UserSpace ListFormat ObjNamLib ObjType QusEc

Getting started: using the SQL INSERT statement

21

____ Use the following command to create the POBJLIST module:
CRTSQLRPGI OBJ(RPG_SQL/POBJLIST) SRCFILE(RPG_SQL/QRPGLESRC) COMMIT(*NONE) OBJTYPE(*MODULE) CLOSQLCSR(*ENDMOD) DBGVIEW(*SOURCE)

On the AS/400, there are two ways to refer to a table in a library when using embedded SQL. One way is shown in the program, the library/table format. This is the familiar format used in OS/400 and CL commands. It is not the way that SQL refers to the path to a table. SQL uses the syntax library.table. When you use SQL syntax, the compiler does not search the library list for tables; you must enter the complete path. However, the SQL naming syntax is what the rest of the universe, outside of the AS/400, uses. So if you are concerned about portable code and you don't need to use the library list, you may decide to use the SQL naming convention. The naming convention is specified on the CRTSQLRPGI command in the OPTION Parameter. In addition to several other values for the parameter, the default value *SYS is used to specify the system naming convention. To use the SQL naming convention, you specify *SQL in the parameter. For the purposes of this manual, I use the default of OS/400 system naming. Bottom line — it's up to you. Just don't choose SQL naming and then specify library/table in your SQL code! It won't work!

2.8.5 Review the POBJLIST module
The POBJLIST module does the following:
• • • •

Accepts an input parameter of a library name to list objects for Drops (deletes) and creates table RPG_SQL/OBJINF for use in the program Creates user space QTEMP/POBJLIST for use with the List Objects API Calls the QUSLOBJ (List Objects) API to list objects in the specified library to the user space Loops through the object list entries in the user space and inserts data from each list entry into table OBJINF

Procedure prototype The first thing the program does is declare a procedure prototype for the CrtUsrSpc procedure in the CRTUSRSPC module that you created in Section 2.8.2. Work fields and constants This section of the code is used to define work fields and constants used in the module. The constants USRSPC_NAME and USRSPC_LIB are used to set the values for the user space name and library. The actual value is set in data structure UserSpace, which is the field passed as a parameter to the CrtUsrSpc procedure.

22

Getting started: using the SQL INSERT statement

Generic user space header When you use a list API like QUSLOBJ (as in this module), the API writes a data structure into the user space that contains header information. The header is followed in the user space by a repeating section containing the elements of the list. One of the elements in the header is the offset to the list element section. Thus the pointer to the user space plus the offset to the list section yields the address of the list section in the user space. Because the header information section is commonly used, IBM provides RPG source code that you can include in your programs to work with the header. The user space header is in one of two possible formats, which in RPG are described as data structures. In this program, the QUSH0300 format is used. The data structure is copied from source member QSYSINC/QRPGLESRC(QUSGEN). Note: library QSYSINC is installed as option 13 of OS/400, System Openness Includes. The keyword Based(GenHeaderPtr) at the start of the QUSH0300 data structure means that GenHeaderPtr is a pointer to the QUSH0300 data structure. You do not need to define GenHeaderPtr separately, as the compiler defines the pointer based on its usage here. The offset length is stored in subfield QUSOLD00 in QUSH0300. List format When you use a list API (for example, to list data about files, spool file, or objects), the API returns data about each object listed in a defined format. To make it easier to use the APIs, IBM provides definitions of the formats as ILE RPG data structures in source file QSYSINC/QRPGLESRC. Each API may have several different data structures associated with it. The data structure you use depends on how much information the API returns to your program. In this example, the QUSLOBJ API is used to return object information, so the data structure format used is QUSL030000. Variable ListPtr is defined as a pointer to the QUSL030000 data structure, simply by specifying Based(ListPtr) to the right of the data structure name. Main routine The program parameter InLib is used as the name of the library containing objects to be listed. The Setup subroutine is executed to create the user space and fill it with the list of objects in the specified library. Upon returning from Setup, pointer GenHeaderPtr points to the header section of the user space. By adding to it the offset to the element list section (field QUSOLD00), ListPtr will point to the first element in the list, describing the first object. QUSNBRLE00 contains the number of elements in the list. QUSIS02 has status information about the success of retrieving the list element; if the list element was retrieved successfully, its data is inserted into the table in subroutine InsObjInf. The variable QUSSEE00 contains the length of each list element. After processing the current element, ListPtr is incremented by QUSSEE00 so that it points to the next element in the list.

Getting started: using the SQL INSERT statement

23

InsObjInf subroutine This subroutine contains an embedded SQL INSERT statement. The INSERT statement does not stipulate the column names because it inserts data into all the columns in the table (see the CREATE TABLE statement in subroutine Setup). The host variables contain the values being inserted. The host variable names are preceded by a colon (:). The INSERT statement is contained within the /EXEC SQL and /END-EXEC directives that delimit the SQL block. That's all there is to it. Don't forget the following! 1) The plus sign (+) after the C for each SQL continuation line. 2) The colon (:) before the name of each host variable (a host variable is any program defined field). 3) The comma between host variables. Don’t put a trailing comma after the last variable, the compile fails if you do. Setup subroutine The Setup subroutine does a number of things:

Uses an SQL DROP TABLE statement to drop the existing OBJINF table, if it exists. Uses an SQL CREATE TABLE statement to create table RPG_SQL/OBJINF. Invokes the CrtUsrSpc function (in module CrtUsrSpc) to create user space QTEMP/POBJLIST. Calls the QUSLOBJ API to list objects in the specified library to the user space. User space name List format name (OBJL0300) Library containing objects to be listed Type of objects to list (*ALL)

• •

When calling the QUSLOBJ API, the parameters are:
• • • •

List APIs are written very efficiently. You must tell the API how much information to return for each list element by specifying the list format name (the second parameter). You use different formats to return more or less information about the objects.

24

Getting started: using the SQL INSERT statement

A word about the QUSEC standard error code data structure, which is commented out on the call to QUSLOBJ. QUSEC is an optional parameter for most APIs. In one of my tests, I left out the library name of the user space. Although the API was called with no apparent error, the objects were not being listed to the user space. Since I had included the optional error code data structure, the program did not blow up, and a status code told me the retrieval had been partially successful. I did not have any code to check the error data structure, and I couldn't figure out what was wrong. When I commented out the QUSEC parameter on the call to QUSLOBJ, recompiled and ran the program again, it immediately blew up at the offending line with a meaningful message in my job log. Moral of the story: either don't include the error code data structure at all, or check it in your code to see if there is a problem.

2.9 Create and run the POBJLIST program
The POBJLIST program is created from the two modules CRTUSRSPRC and POBJLIST. Note that is OK to have a program object (*PGM) and module object (*MODULE) of the same name in a library. ____ Enter the following command to create the POBJLIST program:
CRTPGM PGM(RPG_SQL/POBJLIST) MODULE(RPG_SQL/POBJLIST RPG_SQL/CRTUSRSPC)

This command binds the modules CRTUSRSPC and POBJLIST to create program POBJLIST. The first module listed (POBJLIST) is considered to be the entry module, since the default value of the ENTMOD parameter is *FIRST. ____ Call the program to list the contents of the RPG_SQL library:
CALL PGM(RPG_SQL/POBJLIST) PARM('RPG_SQL')

____ Start the SQL environment with the STRSQL command. ____ Enter the following SQL statement in the SQL environment:
SELECT * FROM RPG_SQL/OBJINF

____ You should see a listing of objects in the library as shown in Figure 7 on page 26.

Getting started: using the SQL INSERT statement

25

020045

Figure 7: The SELECT statement shows the rows in the OBJINF table.

26

Getting started: using the SQL INSERT statement

2.10 Lab 2–2 — Create an RPG program that uses an INSERT statement
In this lab, you will create a small SQLRPGLE program that declares some host variables in the D–specs, loads values into the host variables and uses the host variables in an SQL INSERT statement. ____ Use your source editor to create member RPG_SQL/QRPGLESRC(TLAB22). Make sure that it’s source type is SQLRPGLE. ____ Declare the following variables in the D–specs, using the specified types and lengths for the data:
Name Data type Length Description

DVNbr DVName DVAddress1 DVCity DVCountry DVCreditRating

CHAR CHAR CHAR CHAR CHAR CHAR

6 18 30 30 18 2

Vendor number Name Address 1 City Country Credit rating

____ Code an embedded SQL statement to drop table RPG_SQL/TVENDOR. ____ Code an embedded SQL statement to create table RPG_SQL/TVENDOR, defined as shown in the following table:
Name Data type Length Description

VNbr VName VAddress1 VAddress2 VCity VCountry VZip VCreditRating

CHAR CHAR CHAR CHAR CHAR CHAR CHAR CHAR

6 18 30 30 30 18 9 2

Vendor number Name Address 1 Address 2 City Country Postal code Credit rating

____ Use the eval opcode to load the following values into the host variables:
Variable Value

DVNbr DVName DVAddress1 DVCity DVCountry DVCreditRating

V98765 China Factory 20345 Happy Progress Court Shanghai China A1

Getting started: using the SQL INSERT statement

27

____ Code an embedded SQL INSERT statement to insert the host variables into the RPG_SQL/TVENDOR table columns. Note that because you are not inserting a value for every column (there is no value given to VAddress2 and VZip), the INSERT statement must use this syntax:
INSERT INTO RPG_SQL/TVENDOR ( :VNbr, ..., :VCreditRating) VALUES('ABCD', ..., 'A2')

Note that a list of columns is specified, then a list of values in the VALUES clause. ____ Compile the program using this command:
CRTSQLRPGI OBJ(RPG_SQL/TLAB22) SRCFILE(RPG_SQL/RPGLESRC) COMMIT(*NONE) CLOSQLCSR(*ENDMOD) DBGVIEW(*SOURCE)

Note: the CRTSQLRPGI command can create either a program or an ILE Module. The default for compiler parameter OBJTYPE is *PGM. ____ Call the program. ____ Enter the following select statement in the SQL environment (STRSQL) to view the table:
SELECT * FROM RPG_SQL/TVENDOR

____ You should see the results shown in Figure 8. Use F20 to shift the display to the right to see the remaining columns.

020035

Figure 8: The row added to the TVENDOR table (first four columns).

____ If you are uncertain what the code should look like, you can use source member RPG_SQL/QRPGLESRC(LAB22) as a guide. 28 Getting started: using the SQL INSERT statement

SQL for RPG Programmers
Get your copy of this important training now:
http://www.Lab400.com/product_detail.asp?prod_id=204

Sign up to vote on this title
UsefulNot useful