15
Embedded SQL in PL/I 10 1. PROGRAMMING IN PL/1....................................................2 1.1 INTRODUCTION............................................................2 1.2 EMBEDDED SQL...........................................................2 1.3 HOST VARIABLES..........................................................2 1.4 THE CURSOR PRINCIPLE....................................................4 1.5 TABLE DECLARATION........................................................6 3.6 CHECK OF THE EXECUTION...................................................8 1.7 NULL INDICATOR.........................................................10 1.8 COMMIT-ROLLBACK......................................................10 Kurt Van Diest / PFI document.doc Tel. (016) 30 23 02 V-20 July 2004 24 March 2000

EMB SQL in PLI

Embed Size (px)

Citation preview

Embedded SQL in PL/I 10

1. PROGRAMMING IN PL/1....................................................................................................................... 2

1.1 INTRODUCTION........................................................................................................................................... 21.2 EMBEDDED SQL......................................................................................................................................... 21.3 HOST VARIABLES........................................................................................................................................ 21.4 THE CURSOR PRINCIPLE............................................................................................................................ 41.5 TABLE DECLARATION.................................................................................................................................. 63.6 CHECK OF THE EXECUTION.......................................................................................................................... 81.7 NULL INDICATOR..................................................................................................................................... 101.8 COMMIT-ROLLBACK........................................................................................................................... 10

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

Embedded SQL in PL/I 10

1. Programming in PL/1

1.1 Introduction

SQL can be used in different programming languages and environments. When SQL is coded in a programming language, it is called embedded SQL. Here we will specifically consider programming in PL/1 and an MVS environment.

First and foremost, we have to make a distinction between static and dynamic embedded SQL:

- static embedded SQL: the statements to be executed are fully known at the time of programming, e.g. SQL in PL/1 programs within the bank.

- dynamic embedded SQL: the statements to be executed are still not known at the time of programming. The SQL statements will only be known upon execution, e.g. SQL in QMF.

1.2 Embedded SQL

The structure of our program will remain the same.To execute an SQL statement, we have to start with ‘EXEC SQL’ and end with a ‘;’ For example:

1.3 Host variables

We will use PLI variables in our SQL statements in order to use the result of our SQL operations or to put variables in the WHERE clause. PLI variables are called host variables.

Host variables are used to pass on values from SQL to PLI, (for example, the result of a SELECT statement) or from PLI to SQL (for example in the WHERE clause, the VALUES statement with INSERT, etc.).

Host variables are defined as ordinary PL/1 variables. When used in an SQL, statement they are always preceded by a ‘:’. When used in PL/1 statements, this colon is not needed.

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

EXEC SQL SELECT * INTO .... FROM F3.TF30004 WHERE ..... ;

Embedded SQL in PL/I 10

However, it is important for these host variables to have a format that corresponds to that of the DB2 columns:

DB2 format PL/1 format

SMALLINT BIN FIXED (15)

INTEGER BIN FIXED (31)

DECIMAL (P,Q) DEC FIXED (P,Q)

CHAR(N) CHAR(N)

VARCHAR(M) CHAR(M) VAR

LONG VARCHAR CHAR(X) VAR

DATE CHAR(10)

TIME CHAR(8)

TIMESTAMP CHAR(26)

A host variable can have a structure with two levels and can be used in all SQL statements.

The use of host variables:

A) To save the result if the result is one row.

We can proceed further in our program with this host variable.

For example:

B) We can also use a variable in the WHERE clause of SELECT, UPDATE or DELETE statements.

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

EXEC SQL SELECT CMUALF INTO :W_CMUALF FROM F3.TF30004 WHERE CLAALF = ‘FRA’;

IF W_CMUALF = ‘FRF’ THEN W_CURRENCY = ‘FRENCH FRANK’;ELSE ...

Embedded SQL in PL/I 10

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

EXEC SQLSELECT COUNT(COCOMP) INTO :W_SOM_COCOMPFROM F3.TF30013 WHERE RCIFD = :W_RCIFD;

Embedded SQL in PL/I 10

C) We can also use host variables to update a table.

D) With the INSERT statement.

1.4 The CURSOR principle

The method described above for retrieving information and putting it in host variables cannot be used if the result of the query is more than one row. We will use a cursor to process multiple rows one by one.

The cursor mechanism works in a similar way to an ordinary file:- cursor declaration - open- read (to cursor end)- close

1) Cursor declaration For the declaration, we will put the SQL statement, together with any host variables, into the WHERE clause, but not after the SELECT with INTO (see above).The host variables have to be declared before the cursor.

SYNTAX:

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

W_NEW_BALANCE = W_OLD_BALANCE + W_ENTRY;EXEC SQL UPDATE F4.TF42001 SET BEFFEC = :W_NEW_BALANCE WHERE RCIFD = :W_RCIFD AND RCIF = :W_RCIF AND CACCT1 = :W_CACCT1 AND CMUALF =:W_CMUALF AND RVOLG = :W_RVOLG;

EXEC SQL INSERT INTO F3.TF30004 VALUES (:W_CCOSYS, :W_CTAAL, :W_CLAALF, :W_CREGIO , :W_CBCKUP);

EXEC SQL DECLARE cursor name CURSOR {WITH HOLD} FORSELECT column,column,...FROM table(s)WHERE where clause ;

Embedded SQL in PL/I 10

WITH HOLD: indicates that the cursor has to be opened with COMMIT or ROLLBACK.

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

Embedded SQL in PL/I 10

2) OpenBy opening the cursor, the rows are selected and the SQL statement is actually executed. A check after this statement will not determine whether rows have been selected, only whether the SQL statement has been correctly executed. This can only be established with the first FETCH (read).

SYNTAX:

3) Fetch Using the FETCH instruction, we will transfer one row from the result to the host variables.Syntax:

With the first FETCH, we can see whether or not something has been selected. Generally, fetch runs in a loop for as long as rows are found (SQLCODE = 0). When the end of the cursor row is reached (SQLCODE = 100) or if there is an error (SQLCODE < 0), we will leave the loop.

4) CloseAfter the processing, we will close the cursor again. If we have defined a cursor without HOLD, the cursor will be implicitly closed with COMMIT or ROLLBACK.

Syntax:

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

EXEC SQL OPEN cursor name ;

EXEC SQL FETCH cursor nameINTO :host variable1,:host variable2,... ;

EXEC SQL CLOSE cursor name ;

Embedded SQL in PL/I 10

1.5 Table declaration

To be able to use a table in our program, a description of this table will have to be given. This description is used to check the syntax at precompilation (see further). Example:

Generally, we do not have to provide this table description ourselves. Whenever a table is created or changed, a DCLGEN (=declaration generator) will be created. This DCLGEN contains an SQL and PL/1 description of the table, and is located in these two libraries: ‘PDP.DB2DCLPL.CCB00’ (for the development environments) and ‘PDP.DB2DCLPL.CCM00’ (for production environments). The name of the DCLGEN is the same as the table name: table F0.TF00008 dclgen TF00008. To be able to use the DCLGEN in the program, we will have to include it.

This command ensures that the DCLGEN is copied in for compilation.

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

EXEC SQL DECLARE F2.TF20020 TABLE

( DBGGLD DECIMAL(9,0) NOT NULL, DEIGLD DECIMAL(9,0) NOT NULL, CMUT CHAR(1) NOT NULL, DMUT DECIMAL(9,0) NOT NULL, DUMUT DECIMAL(7,0) NOT NULL, CUSRID CHAR(8) NOT NULL, DSCHRA DECIMAL(9,0) NOT NULL, RUSEVW CHAR(8) NOT NULL, CLOGBL CHAR(1) NOT NULL, RVERS CHAR(2) NOT NULL, CSTATU CHAR(1) NOT NULL, CLAALF CHAR(3) NOT NULL, CREGIO CHAR(5) NOT NULL, CTAAL DECIMAL(3,0) NOT NULL, NLAND CHAR(40) NOT NULL, NLANDK CHAR(15) NOT NULL, CVLREG CHAR(1) NOT NULL ) ;

EXEC SQL INCLUDE TF00008 ;

Embedded SQL in PL/I 10

This DCLGEN thus appears as follows:

It is preferable to use these PL/1 variables since they are automatically copied in together with the DB2 declaration.Note that in this example, the PL/1 declaration is preceded by ‘EXEC SQL BEGIN DECLARE SECTION’ and followed by ‘EXEC SQL END DECLARE SECTION’. This is not needed when the program is only executed in MVS, but it is when the program is also to be executed in a VM environment (as another DB system runs there, i.e. SQL/DS).

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

/*********************************************************************/ /* DCLGEN TABLE(F0.TF00008) */ /* LIBRARY(PDT.DCLGEN.U32332.D170300.T103407.LIST(TF00008)) */ /* ACTION(REPLACE) */ /* LANGUAGE(PLI) */ /* STRUCTURE(TF00008) */ /* APOST */ /* LABEL(YES) */ /* ... IS THE DCLGEN COMMAND THAT MADE THE FOLLOWING STATEMENTS */ /*********************************************************************/ EXEC SQL DECLARE F0.TF00008 TABLE ( CCOSYS CHAR(2) NOT NULL, CTAAL DECIMAL(3,0) NOT NULL, CLAALF CHAR(3) NOT NULL, CREGIO CHAR(5) NOT NULL, CBCKUP CHAR(1) NOT NULL ) ;

/*********************************************************************/ /* PLI DECLARATION FOR TABLE F0.TF00008 */ /*********************************************************************/ EXEC SQL BEGIN DECLARE SECTION; DCL 1 TF00008, 5 CCOSYS CHAR(2), 5 CTAAL DEC FIXED(3,0), 5 CLAALF CHAR(3), 5 CREGIO CHAR(5), 5 CBCKUP CHAR(1); /*********************************************************************/ /* THE NUMBER OF COLUMNS DESCRIBED BY THIS DECLARATION IS 5 */ /*********************************************************************/ EXEC SQL END DECLARE SECTION;

Embedded SQL in PL/I 10

3.6 Check of the execution

After an SQL operation has been executed, using the SQLCODE we have to check whether an error has occurred, whether something has been found, etc. After each SQL statement the SQLCODE has to be checked! The SQLCODE can be divided into three major groups:

SQLCODE > 0 WARNING Exceptional but executed condition

(e.g. no row found (SQLCODE = 100))SQLCODE = 0 OKSQLCODE < 0 ERROR Error during execution of the SQL statement

(e.g. -803, a row has been added with a key that already exists)

The most common SQLCODES for each statement are:

STATEMENT SQLCODE COMMENTSSELECT 0 Requested information

found+100 Row not found

INSERT 0 Addition successful-803 Key for the added row

already exists UPDATE 0 Change successful

+100 Row not foundDELETE 0 Row deleted

+100 Row not foundOPEN cursor 0 Select statement for cursor

correctly executed FETCH 0 Row fetched

+100 No (further) row found CLOSE cursor 0 Cursor correctly closed

The SQLCODE is a component of the SQL Communication Area (abbreviated to SQLCA). In order to use the SQLCODE, we thus also have to include the SQLCA. The method is the same as with DECLGEN, for ex.

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

EXEC SQL INCLUDE SQLCA ;

Embedded SQL in PL/I 10

The declaration below is copied into the program:

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

DECLARE 1 SQLCA, 2 SQLCAID CHAR(8), 2 SQLCABC FIXED(31) BINARY, 2 SQLCODE FIXED(31) BINARY, 2 SQLERRM CHAR(70) VAR, 2 SQLERRP CHAR(8), 2 SQLERRD(6) FIXED(31) BINARY, 2 SQLWARN, 3 SQLWARN0 CHAR(1), 3 SQLWARN1 CHAR(1), 3 SQLWARN2 CHAR(1), 3 SQLWARN3 CHAR(1), 3 SQLWARN4 CHAR(1), 3 SQLWARN5 CHAR(1), 3 SQLWARN6 CHAR(1), 3 SQLWARN7 CHAR(1), 2 SQLEXT, 3 SQLWARN8 CHAR(1), 3 SQLWARN9 CHAR(1), 3 SQLWARNA CHAR(1), 3 SQLSTATE CHAR(5);

Embedded SQL in PL/I 10

1.7 NULL indicator

If a column can contain the NULL value or if we use a function that can return a NULL value (e.g. MAX(column) when no row satisfies that criterion), we cannot check it using the SQLCODE as it will contain the value 0.Hence we will have to use an indicator field. When this indicator field is negative, it means that the result of the query cannot be used for further processing. The host variable does not contain any correct information. Note that the null indicator is written directly against the host variable, thus without spaces or commas in between!

Example:

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

DCL NULLVAR BIN FIXED(15);

EXEC SQL SELECT MIN(COCOMP) INTO :TF30013.COCOMP:NULLVAR FROM F3.TF30013 WHERE RCIFD = :TF30013.RCIFD;

IF SELECT = 0 THEN DO; IF NULLVAR < 0 THEN DO; processing END; ELSE DO; processing END; END;ELSE Processing error

Embedded SQL in PL/I 10

1.8 COMMIT-ROLLBACK

If the program changes data in the tables, this will only be temporary. It is only by executing a COMMIT (implicit or explicit) that the changes are passed on. When the program is executed correctly (i.e. without abend), a commit will be done automatically on MVS. When a program is executed on VM we will have to write an explicit commit. We can also pass on a commit explicitly.Rollback will ensure that the changes up to the previous commit are undone. This will be done implicitly with an abend.We can also explicitly do a commit or a rollback:

or

It is useful to do a commit now and again, certainly when a cursor is used. This is so that if the program goes abend, not all changes will be undone. A commit has to be done after a logical processing unit, i.e. if a number of tables have been changed. You have to ensure that with an abend and restart, the data in the various tables are still consistent.

Kurt Van Diest / PFI document.docTel. (016) 30 23 02 V-20 July 2004

24 March 2000

EXEC SQL COMMIT WORK;

EXEC SQL ROLLBACK WORK;