PK FJoa,mimetypeapplication/epub+zipPKFJOEBPS/pco03dbc.htm Database Concepts

3 Database Concepts

This chapter explains the CONNECT statement and its options, Oracle Net, and related network connection statements. Transaction processing is presented. You learn the basic techniques that safeguard the consistency of your database, including how to control whether changes to Oracle data are made permanent or undone.

Connecting to Oracle

Your Pro*COBOL program must log on to Oracle before querying or manipulating data. To log on, you use the CONNECT statement, as in

     EXEC SQL 
         CONNECT :USERNAME IDENTIFIED BY :PASSWD
     END-EXEC. 

where USERNAME and PASSWD are PIC X(n) or PIC X(n) VARYING host variables. Alternatively, you can use the statement:

     EXEC SQL 
         CONNECT :USR-PWD 
     END-EXEC. 

where the host variable USR-PWD contains your username and password separated by a slash (/) followed by an optional tnsnames.ora alias (@TNSALIAS).

The syntax for the CONNECT statement has an optional ALTER AUTHORIZATION clause. The complete syntax for CONNECT is shown here:

     EXEC SQL 
        CONNECT { :user IDENTIFIED BY :oldpswd | :usr_psw }
        [[AT { dbname | :host_variable }] USING :connect_string ]
        [ {ALTER AUTHORIZATION :newpswd  | IN {SYSDBA | SYSOPER} MODE} ]
     END-EXEC.

The ALTER AUTHORIZATION clause is explained in "Changing Passwords at Runtime". The SYSDBA and SYSOPER options are explained in "SYSDBA or SYSOPER Privileges" .

The CONNECT statement must be the first SQL statement executed by the program. That is, other executable SQL statements can positionally, but not logically, precede the CONNECT statement. If the precompiler option AUTO_CONNECT=YES, a CONNECT statement is not needed.)

To supply the username and password separately, you define two host variables as character strings or VARCHAR variables. If you supply a userid containing both username and password, only one host variable is needed.

Make sure to set the username and password variables before the CONNECT is executed or it will fail. Your program can prompt for the values or you can hard-code them, as follows:

 WORKING STORAGE SECTION. 
     ... 
 01  USERNAME  PIC X(10). 
 01  PASSWD    PIC X(10). 
         ... 
     ... 
 PROCEDURE DIVISION. 
 LOGON. 
     EXEC SQL WHENEVER SQLERROR GOTO LOGON-ERROR END-EXEC. 
     MOVE "SCOTT" TO USERNAME. 
     MOVE "TIGER" TO PASSWD. 
     EXEC SQL 
         CONNECT :USERNAME IDENTIFIED BY :PASSWD 
     END-EXEC. 

However, you cannot hard-code a username and password into the CONNECT statement or use quoted literals. For example, the following statements are invalid:

     EXEC SQL 
         CONNECT SCOTT IDENTIFIED BY TIGER 
     END-EXEC. 

     EXEC SQL 
         CONNECT "SCOTT" IDENTIFIED BY "TIGER" 
     END-EXEC.

Default Databases and Connections

It is possible within a Pro*COBOL program to maintain more than one database connection at the same time.

Concurrent Logons

Pro*COBOL supports distributed processing through Oracle Net. Your application can concurrently access any combination of local and remote databases or make multiple connections to the same database. In Figure 3-1, an application program communicates with one local and three remote Oracle databases. ORA2, ORA3, and ORA4 are logical names used in CONNECT statements.

Figure 3-1 Connecting Through Oracle

Connecting Through Oracle

By eliminating the boundaries in a network between different machines and operating systems, Oracle Net provides a distributed processing environment for Oracle tools. This section shows you how the Pro*COBOL supports distributed processing through Oracle Net. You learn how your application can

  • Access other databases directly or indirectly

  • Concurrently access any combination of local and remote databases

  • Make multiple connections to the same database

Normally you would need only a single connection, achieved by EXEC SQL CONNECT :USR-PWD END-EXEC. The database that is connected to is determined by what USR-PWD contains. If it contains the username and password for the default database, it will connect to the database defined as the default for the session. If it contains username/password@REMDB" it will connect through Oracle Net to the REMDB database as defined by your Oracle Net configuration. (An alternative is to use the USING clause to specify the Oracle Net connection string.) This is the default connection.

To make further concurrent connections to either the same or different databases you make use of the AT clause, that is, EXEC SQL AT DB1 CONNECT :USR-PWD END-EXEC. The name after the AT clause uniquely identifies a "nondefault" connection, and any SQL statements with the same name after the AT clause are executed against that connection. If the AT clause is omitted in an SQL statement then the statement is executed against the default connection.

All database names must be unique, but two or more database names can specify the same connection. That is, you can have multiple connections to any database on any node.

Using Username/Password

Usually, you establish a connection to Oracle as follows:

     EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWORD END-EXEC.

Or you can use:

     EXEC SQL CONNECT :USR-PWD END-EXEC. 

where USR-PWD contains any valid Oracle connect string.

You can also log on automatically, as shown in "Automatic Logons".

These are simplified subsets of the CONNECT statement. For all details, read the next sections in this chapter and also see "CONNECT (Executable Embedded SQL Extension)".

Named Database Connections

In the following example, you connect to a named database. Normally you use a named database connection only for multiple concurrent connections. The following example shows the syntax for a single connection:

* --  Declare necessary host variables
 WORKING-STORAGE SECTION.
     ...
     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
 01  USERNAME  PIC X(10) .
 01  PASSWORD  PIC X(10) .
 01  DB-STRING PIC X(20) .
        ...
     EXEC SQL END DECLARE SECTION END-EXEC.
     ...
 PROCEDURE DIVISION.
     MOVE "scott" TO USERNAME.
     MOVE "tiger" TO PASSSWORD.
     MOVE "nyremote" TO DB-STRING.
      ... 
* --  Assign a unique name to the database connection.
     EXEC SQL DECLARE DBNAME DATABASE END-EXEC.
* --  Connect to the nondefault database
     EXEC SQL
     CONNECT :USERNAME IDENTIFIED BY :PASSWORD 
     AT DBNAME USING :DB-STRING
     END-EXEC.

The identifiers in this example serve the following purposes:

  • The host variables USERNAME and PASSWORD identify a valid user.

  • The host variable DB-STRING contains the Oracle Net syntax for logging on to a nondefault database at a remote node.

  • The undeclared identifier DBNAME names a nondefault connection; it is an identifier used by Oracle, not a host or program variable.

The USING clause specifies the network, machine, and database to be associated with DBNAME. Later, SQL statements using the AT clause (with DBNAME) are executed at the database specified by DB-STRING.

Alternatively, you can use a character host variable in the AT clause, as the following example shows:

* --  Declare necessary host variables
 WORKING-STORAGE SECTION.
     ...
     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
 01  USERNAME  PIC X(10).
 01  PASSWORD  PIC X(10).
 01  DB-NAME   PIC X(10).
 01  DB-STRING PIC X(20).
        ...
     EXEC SQL END DECLARE SECTION END-EXEC.
     ...
 PROCEDURE DIVISION.
     MOVE "scott" TO USERNAME.
     MOVE "tiger" TO PASSSWORD.
     MOVE "oracle1" TO DB-NAME.
     MOVE "nyremote" TO DB-STRING.
     ... 
* --  Connect to the nondefault database
     EXEC SQL
     CONNECT :USERNAME IDENTIFIED BY :PASSWORD 
     AT :DB-NAME USING :DB-STRING
     END-EXEC.

If DB-NAME is a host variable, the DECLARE DATABASE statement is not needed. Only if DBNAME is an undeclared identifier must you execute a DECLARE DBNAME DATABASE statement before executing a CONNECT ... AT DBNAME statement.

SQL Operations. If granted the privilege, you can execute any SQL data manipulation statement at the nondefault connection. For example, you might execute the following sequence of statements:

     EXEC SQL AT DBNAME SELECT ... 
     EXEC SQL AT DBNAME INSERT ... 
     EXEC SQL AT DBNAME UPDATE ... 

In the next example, DB-NAME is a host variable:

     EXEC SQL AT :DB-NAME DELETE ... 

Cursor Control. Cursor control statements such as OPEN, FETCH, and CLOSE are exceptions—they never use an AT clause. If you want to associate a cursor with an explicitly identified database, use the AT clause in the DECLARE CURSOR statement, as follows:

     EXEC SQL AT :DB-NAME DECLARE emp_cursor CURSOR FOR ... 
     EXEC SQL OPEN emp_cursor ... 
     EXEC SQL FETCH emp_cursor ... 
     EXEC SQL CLOSE emp_cursor END-EXEC.

If DB-NAME is a host variable, its declaration must be within the scope of all SQL statements that refer to the declared cursor. For example, if you open the cursor in one subprogram, then fetch from it in another, you must declare DB-NAME globally or pass it to each subprogram.

When opening, closing, or fetching from the cursor, you do not use the AT clause. The SQL statements are executed at the database named in the AT clause of the DECLARE CURSOR statement or at the default database if no AT clause is used in the cursor declaration.

The AT :host-variable clause enables you to change the connection associated with a cursor. However, you cannot change the association while the cursor is open. Consider the following example:

     EXEC SQL AT :DB-NAME DECLARE emp_cursor CURSOR FOR ... 
     MOVE "oracle1" TO DB-NAME.
     EXEC SQL OPEN emp_cursor END-EXEC. 
     EXEC SQL FETCH emp_cursor INTO ... 
     MOVE "oracle2" TO DB-NAME.
* -- illegal, cursor still open 
     EXEC SQL OPEN emp_cursor END-EXEC.
     EXEC SQL FETCH emp_cursor INTO ... 

This is illegal because emp_cursor is still open when you try to execute the second OPEN statement. Separate cursors are not maintained for different connections; there is only one emp_cursor, which must be closed before it can be reopened for another connection. To debug the last example, simply close the cursor before reopening it, as follows:

* -- close cursor first 
     EXEC SQL CLOSE emp_cursor END-EXEC.
     MOVE "oracle2" TO DB-NAME.
     EXEC SQL OPEN EMP-CUROR END-EXEC. 
     EXEC SQL FETCH emp_cursor INTO ... 

Dynamic SQL. Dynamic SQL statements are similar to cursor control statements in that some never use the AT clause. For dynamic SQL Method 1, you must use the AT clause if you want to execute the statement at a nondefault connection. An example follows:

     EXEC SQL AT :DB-NAME EXECUTE IMMEDIATE :SQL-STMT END-EXEC.
 

For Methods 2, 3, and 4, you use the AT clause only in the DECLARE STATEMENT statement if you want to execute the statement at a nondefault connection. All other dynamic SQL statements such as PREPARE, DESCRIBE, OPEN, FETCH, and CLOSE never use the AT clause. The next example shows Method 2:

     EXEC SQL AT :DB-NAME DECLARE SQL-STMT STATEMENT END-EXEC. 
     EXEC SQL PREPARE SQL-STMT FROM :SQL-STRING END-EXEC. 
     EXEC SQL EXECUTE SQL-STMT END-EXEC. 

The following example shows Method 3:

     EXEC SQL AT :DB-NAME DECLARE SQL-STMT STATEMENT END-EXEC. 
     EXEC SQL PREPARE SQL-STMT FROM :SQL-STRING END-EXEC. 
     EXEC SQL DECLARE emp_cursor CURSOR FOR SQL-STMT END-EXEC. 
     EXEC SQL OPEN emp_cursor ... 
     EXEC SQL FETCH emp_cursor INTO ... 
     EXEC SQL CLOSE emp_cursor END-EXEC. 

You need not use the AT clause when connecting to a remote database unless you open two or more connections simultaneously (in which case the AT clause is needed to identify the active connection). To make the default connection to a remote database, use the following syntax:

     EXEC SQL 
        CONNECT :USERNAME IDENTIFIED BY :PASSWORD USING :DB-STRING
     END-EXEC.

Automatic Logons

You can log on to Oracle automatically with the userid:

<prefix><username> 

where prefix is the value of the Oracle initialization parameter OS_AUTHENT_PREFIX (the default value is OPS$) and username is your operating system user or task name. For example, if the prefix is OPS$, your user name is TBARNES, and OPS$TBARNES is a valid Oracle userid, then you log on to Oracle as user OPS$TBARNES.

To take advantage of the automatic logon feature, you simply pass a slash (/) character to Pro*COBOL, as follows:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01 ORACLEID   PIC X.
     ...
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
     MOVE '/' TO ORACLEID.
     EXEC SQL CONNECT :ORACLEID END-EXEC. 

This automatically connects you as user OPS$username. For example, if your operating system username is RHILL, and OPS$RHILL is a valid Oracle username, connecting with a slash (/) automatically logs you on to Oracle as user OPS$RHILL.

You can also pass a character string to Pro*COBOL. However, the string cannot contain trailing blanks. For example, the following CONNECT statement will fail:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
           01 ORACLEID   PIC X(5).
     ...
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
     MOVE '/    ' TO ORACLEID.
     EXEC SQL CONNECT :ORACLEID END-EXEC.

The AUTO_CONNECT Precompiler Option

Pro*COBOL lets your program log on to the default database without using the CONNECT statement. Simply specify the precompiler option AUTO_CONNECT on the command line.

Assume that the default value of OS_AUTHENT_PREFIX is OPS$, your username is TBARNES, and OPS$TBARNES is a valid Oracle userid. When AUTO_CONNECT=YES, as soon as Pro*COBOL encounters an executable SQL statement, your program logs on to Oracle automatically with the userid OPS$TBARNES.

When AUTO_CONNECT=NO (the default), you must use the CONNECT statement to log on to Oracle.

Changing Passwords at Runtime

Pro*COBOL provides client applications with a convenient way to change a user password at runtime through the optional ALTER AUTHORIZATION clause.

The syntax for the ALTER AUTHORIZATION clause is shown here:

     EXEC SQL CONNECT .. ALTER AUTHORIZATION :NEWPSWD END-EXEC.

Using this clause indicates that you want to change the account password to the value indicated by NEWPSWD. After the change is made, an attempt is made to connect as USER/NEWPSWD. This can have the following results:

  • The application will connect without issue.

  • The application will fail to connect. This could be due to either of the following:

    • Password verification failed for some reason. In this case the password remains unchanged.

    • The account is locked. Changes to the password are not permitted.

Connect Without Alter Authorization

This section describes the possible outcomes of different variations of the CONNECT statement.

Standard CONNECT

If an application issues the following statement:

      EXEC SQL CONNECT ...   /* No ALTER AUTHORIZATION clause */

it performs a normal connection attempt. The possible results include the following:

  • The application will connect without issue.

  • The application will connect, but will receive a password warning. The warning indicates that the password has expired but is in a grace period which will allow logons. At this point, the user is encouraged to change the password before the account becomes locked.

  • The application will fail to connect. Possible causes include the following:

    • The password is incorrect.

    • The account has expired, and is possibly in a locked state.

SYSDBA or SYSOPER Privileges

Before Oracle release 8.1 you did not have to use this clause to have the SYSOPER or SYSDBA system privilege, but now you must.

Append the following optional string to the CONNECT statement after all other clauses if you want to log on with either SYSDBA or SYSOPER system privileges:

IN { SYSDBA | SYSOPER } MODE

For example:

EXEC SQL CONNECT ... IN SYSDBA MODE END-EXEC.

Here are the restrictions that apply to this option:

  • This option is not supported when using the AUTO_CONNECT=YES precompiler option setting.

  • The option is not permitted when using the ALTER AUTHORIZATION keywords in the CONNECT statement.

Using Links

Database links are supported through the Oracle distributed database option. For example, a distributed query allows a single SELECT statement to access data on one or more nondefault databases.

The distributed query facility depends on database links, which assign a name to a CONNECT statement rather than to the connection itself. At runtime, the embedded SELECT statement is executed by the specified database server, which connects implicitly to the nondefault database(s) to get the required data.

For more information, see Oracle Database Net Services Administrator's Guide.

Key Terms

Before delving into the subject of transactions, you should know the terms defined in this section.

The jobs or tasks that the database manages are called sessions. A user session is started when you run an application program or a tool such as Oracle Forms and connect to the database. Oracle enables user sessions to work simultaneously and share computer resources. To do this, Oracle must control concurrence, the accessing of the same data by many users. Without adequate concurrence controls, there might be a loss of data integrity. That is, changes to data or structures might be made in the wrong order.

Oracle uses locks to control concurrent access to data. A lock gives you temporary ownership of a database resource such as a table or row of data. Thus, data cannot be changed by other users until you finish with it. You need never explicitly lock a resource, because default locking mechanisms protect table data and structures. However, you can request data locks on tables or rows when it is to your advantage to override default locking. You can choose from several modes of locking such as row share and exclusive.

A deadlock can occur when two or more users try to access the same database object. For example, two users updating the same table might wait if each tries to update a row currently locked by the other. Because each user is waiting for resources held by another user, neither can continue until the server breaks the deadlock. The server signals an error to the participating transaction that had completed the least amount of work, and the "deadlock detected while waiting for resource" error code is returned to SQLCODE in the SQLCA.

When a table is queried by one user and updated by another at the same time, the database generates a read consistent view of the table's data for the query. That is, once a query begins (and proceeds), the data read by the query does not change. As update activity continues, the database takes snapshots of the table's data and records changes in a rollback segment. The database uses information in the rollback segment to build read consistent query results and to undo changes if necessary.

How Transactions Guard a Database

The database is transaction oriented; it uses transactions to ensure data integrity. A transaction is a series of one or more logically related SQL statements you define to accomplish some task. The database treats the series of SQL statements as a unit so that all the changes brought about by the statements are either committed (made permanent) or rolled back (undone) at the same time. If your application program fails in the middle of a transaction, the database is automatically restored to its former (pre-transaction) state.

The coming sections show you how to define and control transactions. Specifically, it shows how to:

For details about the SQL statements discussed in this chapter, see the Oracle Database SQL Language Reference.

Beginning and Ending Transactions

You begin a transaction with the first executable SQL statement (other than CONNECT) in your program. When one transaction ends, the next executable SQL statement automatically begins another transaction. Thus, every executable statement is part of a transaction. Because they cannot be rolled back and need not be committed, declarative SQL statements are not considered part of a transaction.

You end a transaction in one of the following ways:

A transaction also ends when there is a system failure or your user session stops unexpectedly because of software problems, hardware problems, or a forced interrupt.

If your program fails in the middle of a transaction, Oracle detects the error and rolls back the transaction. If your operating system fails, Oracle restores the database to its former (pre-transaction) state.

Using the COMMIT Statement

The COMMIT statement is used to make changes to the database permanent. Until changes are committed, other users cannot access the changed data; they see it as it was before your transaction began. The COMMIT statement has no effect on the values of host variables or on the flow of control in your program. Specifically, the COMMIT statement:

When MODE={ANSI13 | ORACLE}, explicit cursors not referenced in a CURRENT OF clause remain open across commits. This can boost performance. For an example, see "Fetching Across Commits".

Because they are part of normal processing, COMMIT statements should be placed inline, on the main path through your program. Before your program terminates, it must explicitly commit pending changes. Otherwise, Oracle rolls them back. In the following example, you commit your transaction and disconnect:

    EXEC SQL COMMIT WORK RELEASE END-EXEC.

The optional keyword WORK provides ANSI compatibility. The RELEASE option frees all resources (locks and cursors) held by your program and logs off the database.

You need not follow a data definition statement with a COMMIT statement because data definition statements issue an automatic commit before and after executing. So, whether they succeed or fail, the prior transaction is committed.

WITH HOLD Clause in DECLARE CURSOR Statements

Any cursor that has been declared with the clause WITH HOLD after the word CURSOR remains open after a COMMIT. The following example shows how to use this clause:

     EXEC SQL 
         DECLARE C1 CURSOR WITH HOLD
         FOR SELECT ENAME FROM EMP
         WHERE EMPNO BETWEEN 7600 AND 7700
 [`    END-EXEC.

The cursor must not be declared for UPDATE. The WITH HOLD clause is used in DB2 to override the default, which is to close all cursors on commit. Pro*COBOL provides this clause in order to ease migrations of applications from DB2 to Oracle. When MODE=ANSI, Oracle uses the DB2 default, but all host variables must be declared in a Declare Section. To avoid having a Declare Section, use the precompiler option CLOSE_ON_COMMIT described next. See "DECLARE CURSOR (Embedded SQL Directive)".

CLOSE_ON_COMMIT Precompiler Option

The precompiler option CLOSE_ON_COMMIT is available to override the default behavior of MODE=ANSI (if you specify MODE=ANSI on the command line, any cursors not declared with the WITH HOLD clause are closed on commit):

CLOSE_ON_COMMIT = {YES | NO} 

The default is NO. This option must be entered only on the command line or in a configuration file.


Note:

Use this option carefully; applications may be slowed if cursors are opened and closed many times because of the need to re-parse for each OPEN statement. See "CLOSE_ON_COMMIT".

Using the ROLLBACK Statement

You use the ROLLBACK statement to undo pending changes made to the database. For example, if you make a mistake, such as deleting the wrong row from a table, you can use ROLLBACK to restore the original data. The ROLLBACK statement has no effect on the values of host variables or on the flow of control in your program. Specifically, the ROLLBACK statement

When MODE={ANSI13 | ORACLE}, explicit cursors not referenced in a CURRENT OF clause remain open across rollbacks.

Because they are part of exception processing, ROLLBACK statements should be placed in error handling routines, off the main path through your program. In the following example, you roll back your transaction and disconnect:

    EXEC SQL ROLLBACK WORK RELEASE END-EXEC.

The optional keyword WORK provides ANSI compatibility. The RELEASE option frees all resources held by your program and logs off the database.

If a WHENEVER SQLERROR GOTO statement branches to an error handling routine that includes a ROLLBACK statement, your program might enter an infinite loop if the rollback fails with an error. You can avoid this by coding WHENEVER SQLERROR CONTINUE before the ROLLBACK statement.

For example, consider the following:

     EXEC SQL
         WHENEVER SQLERROR GOTO SQL-ERROR
     END-EXEC.
     ...
     DISPLAY 'Employee number? '.
     ACCEPT EMP-NUMBER.
     DISPLAY 'Employee name? '.
     ACCEPT EMP-NAME.
     EXEC SQL INSERT INTO EMP (EMPNO, ENAME)
        VALUES (:EMP-NUMBER, :EMP-NAME)
     END-EXEC.
     ...
 SQL-ERROR.
     EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
     DISPLAY 'PROCESSING ERROR.'.
     DISPLAY 'ERROR CODE : ', SQLCODE.
     DISPLAY 'MESSAGE :', SQLERRMC.
     EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
     STOP RUN.

Oracle rolls back transactions if your program terminates abnormally.

Statement-Level Rollbacks

Before executing any SQL statement, Oracle marks an implicit savepoint (not available to you). Then, if the statement fails, Oracle rolls it back automatically and returns the applicable error code to SQLCODE in the SQLCA. For example, if an INSERT statement causes an error by trying to insert a duplicate value in a unique index, the statement is rolled back.

Only work started by the failed SQL statement is lost; work done before that statement in the current transaction is kept. Thus, if a data definition statement fails, the automatic commit that precedes it is not undone.


Note:

Before executing a SQL statement, Oracle must parse it, that is, examine it to make sure it follows syntax rules and refers to valid database objects. Errors detected while executing a SQL statement cause a rollback, but errors detected while parsing the statement do not.

Oracle can also roll back single SQL statements to break deadlocks. Oracle signals an error to one of the participating transactions and rolls back the current statement in that transaction.

Using the SAVEPOINT Statement

The SAVEPOINT embedded SQL statement marks and names the current point in processing a transaction. Each marked point is called a savepoint. For example, the following statement marks a savepoint named start_delete:

    EXEC SQL SAVEPOINT start_delete END-EXEC.

Savepoints let you divide long transactions, giving you more control over complex procedures. For example, if a transaction performs several functions, you can mark a savepoint before each function. Then, if a function fails, you can easily restore the data to its former state, recover, and then reexecute the function.

To undo part of a transaction, you can use savepoints with the ROLLBACK statement and its TO SAVEPOINT clause. The TO SAVEPOINT clause lets you roll back to an intermediate statement in the current transaction. With it, you do not have to undo all your changes. Specifically, the ROLLBACK TO SAVEPOINT statement:

In the following example, you access the table MAIL_LIST to insert new listings, update old listings, and delete (a few) inactive listings. After the delete, you check SQLERRD(3) in the SQLCA for the number of rows deleted. If the number is unexpectedly large, you roll back to the savepoint start_delete, undoing just the delete.

* -- For each new customer
     DISPLAY 'New customer number? '.
     ACCEPT CUST-NUMBER.
     IF CUST-NUMBER = 0
          GO TO REV-STATUS
     END-IF.
     DISPLAY 'New customer name? '.
          ACCEPT  CUST-NAME.
     EXEC SQL INSERT INTO MAIL-LIST (CUSTNO, CNAME, STAT)
         VALUES (:CUST-NUMBER, :CUST-NAME, 'ACTIVE').
     END-EXEC.
     ...
* -- For each revised status
 REV-STATUS.
     DISPLAY 'Customer number to revise status? '.
     ACCEPT CUST-NUMBER.
     IF CUST-NUMBER = 0
         GO TO SAVE-POINT
     END-IF.
     DISPLAY 'New status? '.
     ACCEPT NEW-STATUS.
     EXEC SQL UPDATE MAIL-LIST
        SET STAT = :NEW-STATUS WHERE CUSTNO = :CUST-NUMBER
     END-EXEC.
     ...
* -- mark savepoint
 SAVE-POINT.
     EXEC SQL SAVEPOINT START-DELETE END-EXEC.
     EXEC SQL DELETE FROM MAIL-LIST WHERE STAT = 'INACTIVE'
     END-EXEC.
     IF SQLERRD(3) < 25 
* -- check number of rows deleted
         DISPLAY 'Number of rows deleted is ', SQLERRD(3)
     ELSE
         DISPLAY 'Undoing deletion of ', SQLERRD(3), ' rows'
         EXEC SQL
             WHENEVER SQLERROR GOTO SQL-ERROR
         END-EXEC
         EXEC SQL
             ROLLBACK TO SAVEPOINT START-DELETE
         END-EXEC
     END-IF.
     EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
     EXEC SQL COMMIT WORK RELEASE END-EXEC.
     STOP RUN.
* -- exit program.
     ...
 SQL-ERROR.
     EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
     EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
     DISPLAY 'Processing error'.
* -- exit program with an error.
     STOP RUN.

Note that you cannot specify the RELEASE option in a ROLLBACK TO SAVEPOINT statement.

Rolling back to a savepoint erases any savepoints marked after that savepoint. The savepoint to which you roll back, however, is not erased. For example, if you mark five savepoints, then roll back to the third, only the fourth and fifth are erased. A COMMIT or ROLLBACK statement erases all savepoints.

Using the RELEASE Option

Oracle rolls back changes automatically if your program terminates abnormally. Abnormal termination occurs when your program does not explicitly commit or roll back work and disconnect using the RELEASE embedded SQL statement.

Normal termination occurs when your program runs its course, closes open cursors, explicitly commits or rolls back work, disconnects, and returns control to the user. Your program will exit gracefully if the last SQL statement it executes is either

     EXEC SQL COMMIT WORK RELEASE END-EXEC. 

or

     EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
 

where the token WORK is optional. Otherwise, locks and cursors acquired by your user session are held after program termination until Oracle recognizes that the user session is no longer active. This might cause other users in a multiuser environment to wait longer than necessary for the locked resources.

Using the SET TRANSACTION Statement

You can use the SET TRANSACTION statement to begin a read-only or read/write transaction, or to assign your current transaction to a specified rollback segment. A COMMIT, ROLLBACK, or data definition statement ends a read-only transaction.

Because they allow "repeatable reads," read-only transactions are useful for running multiple queries against one or more tables while other users update the same tables. During a read-only transaction, all queries refer to the same snapshot of the database, providing a multitable, multiquery, read-consistent view. Other users can continue to query or update data as usual. An example of the SET TRANSACTION statement follows:

     EXEC SQL SET TRANSACTION READ ONLY END-EXEC.
 

The SET TRANSACTION statement must be the first SQL statement in a read-only transaction and can appear only once in a transaction. The READ ONLY parameter is required. Its use does not affect other transactions. Only the SELECT (without FOR UPDATE), LOCK TABLE, SET ROLE, ALTER SESSION, ALTER SYSTEM, COMMIT, and ROLLBACK statements are allowed in a read-only transaction.

In the following example, a store manager checks sales activity for the day, the past week, and the past month by using a read-only transaction to generate a summary report. The report is unaffected by other users updating the database during the transaction.

     EXEC SQL SET TRANSACTION READ ONLY END-EXEC. 
     EXEC SQL SELECT SUM(SALEAMT) INTO :DAILY FROM SALES 
         WHERE SALEDATE = SYSDATE END-EXEC.
     EXEC SQL SELECT SUM(SALEAMT) INTO :WEEKLY FROM SALES
         WHERE SALEDATE > SYSDATE - 7 END-EXEC.
     EXEC SQL SELECT SUM(SALEAMT) INTO :MONTHLY FROM SALES 
         WHERE SALEDATE > SYSDATE - 30 END-EXEC. 
     EXEC SQL COMMIT WORK END-EXEC. 
* --  simply ends the transaction since there are no changes 
* --  to make permanent 
* --  format and print report 

Overriding Default Locking

By default, Oracle implicitly (automatically) locks many data structures for you. However, you can request specific data locks on rows or tables when it is to your advantage to override default locking. Explicit locking lets you share or deny access to a table for the duration of a transaction or ensure multitable and multiquery read consistency.

With the SELECT FOR UPDATE OF statement, you can explicitly lock specific rows of a table to make sure they do not change before an update or delete is executed. However, Oracle automatically obtains row-level locks at update or delete time. So, use the FOR UPDATE OF clause only if you want to lock the rows before the update or delete.

You can explicitly lock entire tables using the LOCK TABLE statement.

Using the FOR UPDATE OF Clause

When you DECLARE a cursor, you can meanwhile optionally specify the FOR UPDATE clause, which has the effect of acquiring an exclusive lock on all rows defined by the cursor. This is useful, for example, when you want to base an update on existing rows in a table and want to ensure that they are not meanwhile changed by anyone else.

Note that if you refer to a cursor with the CURRENT OF clause, that the precompiler will automatically add the FOR UPDATE clause to the cursor definition and the word OF is optional. For instance, instead of:

     EXEC SQL DECLARE emp_cursor CURSOR FOR 
         SELECT ENAME, JOB, SAL FROM EMP WHERE DEPTNO = 20 
            FOR UPDATE OF SAL
     END-EXEC.
 

you can drop the OF part of the clause and simply code:

    EXEC SQL DECLARE emp_cursor CURSOR FOR 
        SELECT ENAME, JOB, SAL FROM EMP WHERE DEPTNO = 20 
           FOR UPDATE
    END-EXEC.

For an example, see "Using the CURRENT OF Clause".

Restrictions

You cannot use FOR UPDATE with multiple tables, but you must use FOR UPDATE OF to identify a column in the table that you want locked. Row locks obtained by a FOR UPDATE statement are cleared by a COMMIT, which explains why the cursor is closed for you. If you try to fetch from a FOR UPDATE cursor after a commit, Oracle generates a Fetch out of Sequence error.

Fetching Across Commits

If you want to mix commits and fetches, do not use the CURRENT OF clause. Instead, select the ROWID of each row, and then use that value to identify the current row during the update or delete. Consider the following example:

     EXEC SQL DECLARE emp_cursor CURSOR FOR
         SELECT ENAME, SAL, ROWID FROM EMP WHERE JOB = 'CLERK'
     END-EXEC.
     ...
     EXEC SQL OPEN emp_cursor END-EXEC.
     EXEC SQL WHENEVER NOT FOUND GOTO ...
     PERFORM
     EXEC SQL
         FETCH emp_cursor INTO :EMP_NAME, :SALARY, :ROW-ID
     END-EXEC
     ... 
         EXEC SQL UPDATE EMP SET SAL = :NEW-SALARY
             WHERE ROWID = :ROW-ID
         END-EXEC
         EXEC SQL COMMIT END-EXEC
     END-PERFORM.

Note, however, that the fetched rows are not locked. So, you can receive inconsistent results if another user modifies a row after you read it but before you update or delete it.

Using the LOCK TABLE Statement

Use the LOCK TABLE statement locks one or more tables in a specified lock mode. For example, the following statement locks the EMP table in row share mode. Row share locks allow concurrent access to a table. They prevent other users from locking the entire table for exclusive use.

     EXEC SQL
         LOCK TABLE EMP IN ROW SHARE MODE NOWAIT
     END-EXEC.

The lock mode determines what other locks can be placed on the table. For example, many users can acquire row share locks on a table at the same time, but only one user at a time can acquire an exclusive lock. While one user has an exclusive lock on a table, no other users can insert, update, or delete rows in that table. For more information about lock modes, see the Oracle Database Advanced Application Developer's Guide

The optional keyword NOWAIT tells Oracle not to wait for a table if it has been locked by another user. Control is immediately returned to your program so that it can do other work before trying again to acquire the lock. (You can check SQLCODE in the SQLCA to see if the table lock failed.) If you omit NOWAIT, Oracle waits until the table is available; the wait has no set limit.

A table lock never keeps other users from querying a table, and a query never acquires a table lock. Consequently, a query never blocks another query or an update, and an update never blocks a query. Only if two different transactions try to update the same row will one transaction wait for the other to complete. Table locks are released when your transaction issues a COMMIT or ROLLBACK.

Handling Distributed Transactions

A distributed database is a single logical database comprising multiple physical databases at different nodes. A distributed statement is any SQL statement that accesses a remote node using a database link. A distributed transaction includes at least one distributed statement that updates data at multiple nodes of a distributed database. If the update affects only one node, the transaction is non-distributed.

When you issue a commit, changes to each database affected by the distributed transaction are made permanent. If instead you issue a rollback, all the changes are undone. However, if a network or machine fails during the commit or rollback, the state of the distributed transaction might be unknown or in doubt. In such cases, if you have FORCE TRANSACTION system privileges, you can manually commit or roll back the transaction at your local database by using the FORCE clause. The transaction must be identified by a quoted literal containing the transaction ID, which can be found in the data dictionary view DBA_2PC_PENDING. Some examples follow:

     EXEC SQL COMMIT FORCE '22.31.83' END-EXEC.
     ...
     EXEC SQL ROLLBACK FORCE '25.33.86'END-EXEC.

FORCE commits or rolls back only the specified transaction and does not affect your current transaction. Note that you cannot manually roll back in-doubt transactions to a savepoint.

The COMMENT clause in the COMMIT statement lets you specify a Comment to be associated with a distributed transaction. If ever the transaction is in doubt, the server stores the text specified by COMMENT in the data dictionary view DBA_2PC_PENDING along with the transaction ID. The text must be a quoted literal of no more than  50 characters in length. An example follows:

     EXEC SQL
         COMMIT COMMENT 'In-doubt trans; notify Order Entry'
     END-EXEC.

For more information about distributed transactions, see Oracle Database Concepts.

Guidelines for Transaction Processing

The following guidelines will help you avoid some common problems.

Designing Applications

When designing your application, group logically related actions together in one transaction. A well-designed transaction includes all the steps necessary to accomplish a given task—no more and no less.

Data in the tables you reference must be left in a consistent state. Thus, the SQL statements in a transaction should change the data in a consistent way. For example, a transfer of funds between two bank accounts should include a debit to one account and a credit to another. Both updates should either succeed or fail together. An unrelated update, such as a new deposit to one account, should not be included in the transaction.

Obtaining Locks

If your application programs include SQL locking statements, make sure the users requesting locks have the privileges needed to obtain the locks. Your DBA can lock any table. Other users can lock tables they own or tables for which they have a privilege, such as ALTER, SELECT, INSERT, UPDATE, or DELETE.

Using PL/SQL

If a PL/SQL block is part of a transaction, commits and rollback operations inside the block affect the whole transaction. In the following example, the rollback operation undoes changes made by the update and the insert:

     EXEC SQL INSERT INTO EMP ...
     EXEC SQL EXECUTE
     BEGIN        UPDATE emp 
     ...
         ...
     EXCEPTION
         WHEN DUP_VAL_ON_INDEX THEN
             ROLLBACK;
     END;
     END-EXEC.
     ...

X/Open Applications

For instructions on using the XA interface in X/Open applications, see your Transaction Processing (TP) Monitor user's guide and Oracle Database Advanced Application Developer's Guide.

PKe[PKFJOEBPS/pco14opt.htm Precompiler Options

14 Precompiler Options

This chapter describes the precompiler options of Pro*COBOL. This chapter includes:

The procob Command

The location of Pro*COBOL differs from system to system. Typically, your system manager or DBA defines environment variables or aliases or uses other operating system-specific means to make the Pro*COBOL executable accessible.

To run the Oracle Pro*COBOL Precompiler, you issue the command

procob [option_name=value] [option_name=value] ... 

The option value is always separated from the option name by an equals sign (=), with no white space around the equals sign.

For example, the INAME option specifies the source file to be precompiled. The command:

procob INAME=test

precompiles the file test.pco in the current directory, since Pro*COBOL assumes that the filename extension is .pco.

You need not use a file extension when specifying INAME unless the extension is nonstandard.

Input and output filenames need not be accompanied by their respective option names, INAME and ONAME. When the option names are not specified, Pro*COBOL assumes that the first filename specified on the command line is the input filename and that the second filename is the output filename.

Thus, the command

procob MODE=ANSI myfile myfile.cob

is equivalent to

procob MODE=ANSI INAME=myfile.pco ONAME=myfile.cob

Case-Sensitivity

In general, you can use either uppercase or lowercase for command-line option names and values. However, if your operating system is case-sensitive (as in UNIX for example) you must specify filename values, including the name of Pro*COBOL executable, using the correct combination of upper and lowercase letters.

Note: Option names and option values that do not name specific operating system objects, such as filenames, are not case-sensitive. In the examples in this guide, option names are written in upper case or lower case, and option values are usually in lower case. Filenames, including the name of the Pro*COBOL executable itself, always follow the case conventions used by the operating system on which it is executed.

With some operating systems and user shells, such as UNIX C shell, the ? may need to be preceded by an "escape" character, such as a back-slash (\). For example, instead of procob ?, you might need to use procob \? to list the Pro*COBOL option settings.

Consult your platform-specific documentation.

Actions During Precompilation

During precompilation, Pro*COBOL generates COBOL code that replaces the SQL statements embedded in your host program. The generated code includes data structures that contain the datatype, length, and address of each host variable, as well as other information required by the Oracle runtime library, SQLLIB. The generated code also contains the calls to SQLLIB routines that perform the embedded SQL operations.

Pro*COBOL can issue warnings and error messages. These messages are described in Oracle Database Error Messages.

About the Options

Many useful options are available at precompile time. They let you control how resources are used, how errors are reported, how input and output are formatted, and how cursors are managed.

The value of an option is a literal, which represents text or numeric values. For example, for the option

... INAME=my_test

the value is a string literal that specifies a filename.

For the option

... PREFETCH=100

the value is numeric.

Some options take Boolean values, which you can represent with the strings YES or NO, TRUE or FALSE, or with the integer literals 1 or 0, respectively. For example, the option

... SELECT_ERROR=YES

is equivalent to

... SELECT_ERROR=TRUE

or

... SELECT_ERROR=1

You leave no white space around the equals (=) sign. This is because spaces delimit individual options. For example, you might specify the option AUTO_CONNECT on the command line as follows:

... AUTO_CONNECT=YES

You can abbreviate the names of options unless the abbreviation is ambiguous. For example, you cannot use the abbreviation MAX because it might stand for MAXLITERAL or MAXOPENCURSORS.

A handy reference to the Pro*COBOL options is available online. To see the online display, enter the Pro*COBOL command, with no arguments, at your operating system prompt:

procob

The display gives the name, syntax, default value, and purpose of each option. Options marked with an asterisk (*) can be specified inline as well as on the command line.

Precedence of Option Values

Option values are determined by the following, in order of increasing precedence:

  • A default built in to Pro*COBOL

  • A value set in the system configuration file

  • A value set in a user configuration file

  • A value entered in the command line

  • A value set in an inline specification

For example, the option MAXOPENCURSORS specifies the maximum number of cached open cursors. The built-in Pro*COBOL default value for this option is 10. However, if MAXOPENCURSORS=32 is specified in the system configuration file, the value becomes 32. The user configuration file could set it to yet another value, which then overrides the system configuration value.

If the MAXOPNCURSORS option is set on the command line, the new command-line value takes precedence. Finally, an inline specification takes precedence over all preceding defaults. For more information, see "Entering Precompiler Options".

Macro and Micro Options

Option MODE is known as a macro option. Some newer options, such as END_OF_FETCH, control only one function and are known as micro options. When setting a macro and a micro option, you must remember that the macro option has precedence over micro options. This is the case if, and only if, the macro option is at a higher level of precedence than the micro option. (As described in the section "Precedence of Option Values".) This behavior is a change from releases of Pro*COBOL prior to 8.0.

For example, the default for MODE is ORACLE, and for END_OF_FETCH is 1403. If you specify MODE=ANSI in the user configuration file, Pro*COBOL will return a value of 100 at the end of fetch, overriding the default END_OF_FETCH value of 1403. If you specify both MODE=ANSI and END_OF_FETCH=1403 in the configuration file, then 1403 will be returned. If you specify END_OF_FETCH=1403 in your configuration file and MODE=ANSI on the command line, then 100 will be returned.

The following table lists the values of micro options set by the macro option values:

Table 14-1 How Macro Option Values Set Micro Option Values

Macro OptionMicro Option

MODE=ANSI | ISO

CLOSE_ON_COMMIT=YES

DECLARE_SECTION=YES

END_OF_FETCH=100

DYNAMIC=ANSI

TYPE_CODE=ANSI

MODE=ANSI14 | ANSI13 | ISO14 | ISO13

CLOSE_ON_COMMIT=NO

DECLARE_SECTION=YES

END_OF_FETCH=100

MODE=ORACLE

CLOSE_ON_COMMIT=NO

DECLARE_SECTION=NO

END_OF_FETCH=1403

DYNAMIC=ORACLE

TYPE_CODE=ORACLE


Determining Current Values

You can interactively determine the current value for one or more options by using a question mark on the command line. For example, if you issue the command

procob ?

the complete option set, along with current values, is displayed on your terminal. In this case, the values are those built into Pro*COBOL, overridden by any values in the system configuration file. But if you issue the following command

procob CONFIG=my_config_file.cfg ?

and there is a file named my_config_file.cfg in the current directory, the options from the my_config_file.cfg file are listed with the other default values. Values in the user configuration file supply missing values, and they supersede values built into Pro*COBOL and values specified in the system configuration file.

You can also determine the current value of a single option by simply specifying the option name followed by =? as in

procob MAXOPENCURSORS=?

Entering Precompiler Options

All Pro*COBOL options (except CONFIG) can be entered on the command line or from a configuration file. Many options can also be entered inline. During a given run, Pro*COBOL can accept options from all three sources.

On the Command Line

You enter precompiler options on the command line using ... [option_name=value] [option_name=value] ...


Separate each option with one or more spaces. For example, you might enter the following options:

... ERRORS=no LTYPE=short 

Inline

Enter options inline by coding EXEC ORACLE OPTION statements, using the following syntax:

     EXEC ORACLE OPTION (option_name=value) END-EXEC. 

For example, you might code the following statement:

     EXEC ORACLE OPTION (RELEASE_CURSOR=YES) END-EXEC. 

An option entered inline overrides the same option entered on the command line.

Advantages

The EXEC ORACLE feature is especially useful for changing option values during precompilation. For example, you might want to change the HOLD_CURSOR and RELEASE_CURSOR values on a statement-by-statement basis. Appendix C, "Performance Tuning" shows you how to use inline options to optimize runtime performance.

Specifying options inline is also helpful if your operating system limits the number of characters you can enter on the command line, and you can store inline options in configuration files. These are discussed in the next section.

Scope of EXEC ORACLE

An EXEC ORACLE statement stays in effect until textually superseded by another EXEC ORACLE statement specifying the same option. In the following example, HOLD_CURSOR=NO stays in effect until superseded by HOLD_CURSOR=YES:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMP-NAME    PIC X(20) VARYING.
 01  EMP-NUMBER  PIC S9(4) COMP VALUE ZERO.
 01  SALARY      PIC S9(5)V99 COMP-3 VALUE ZERO.
 01  DEPT-NUMBER PIC S9(4) COMP VALUE ZERO.
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
     EXEC SQL WHENEVER NOT FOUND GOTO NO-MORE END-EXEC. 
     ...
     EXEC ORACLE OPTION (HOLD_CURSOR=NO)END-EXEC. 
     ...
     EXEC SQL DECLARE emp_cursor CURSOR FOR 
        SELECT EMPNO, DEPTNO FROM EMP 
     END-EXEC.
     EXEC SQL OPEN emp_cursor END-EXEC.
  
     DISPLAY 'Employee Number  Dept'.
     DISPLAY '---------------  ----'.
     PERFORM
         EXEC SQL
           FETCH emp_cursor INTO :EMP-NUMBER, :DEPT-NUMBER
         END-EXEC 
         DISPLAY EMP-NUMBER, DEPT-NUMBER END-EXEC
     END-PERFORM. 

 NO-MORE.
         EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC. 
     PERFORM
         DISPLAY 'Employee number? ' 
         ACCEPT EMP-NUMBER 
         IF EMP-NUMBER IS NOT = 0 
             EXEC ORACLE OPTION (HOLD_CURSOR=YES) END-EXEC 
             EXEC SQL SELECT ENAME, SAL 
                 INTO :EMP-NAME, :SALARY 
                 FROM EMP 
                 WHERE EMPNO = :EMP-NUMBER 
                 DISPLAY 'Salary for ', EMP-NAME, ' is ', SALARY
             END-EXEC 
         END-IF
     END-PERFORM. 
  NEXT-PARA.
     ... 

Configuration Files

A configuration file is a text file that contains precompiler options. Each record (line) in the file contains one option, with its associated value or values. For example, a configuration file might contain the lines

FIPS=YES
MODE=ANSI

to set values for the FIPS and MODE options.

There is a single system configuration file for each system. The name of the system configuration file is

pcbcfg.cfg

The location of the file is operating system-specific. On most UNIX systems, the Pro*COBOL configuration file is usually located in the $ORACLE_HOME/precomp/admin directory, where $ORACLE_HOME is the environment variable for the database software.

Note that before release 8.0 of Pro*COBOL, the configuration file was called pccob.cfg.

The Pro*COBOL user can have one or more user configuration files. The name of the configuration file must be specified using the CONFIG command-line option. For more information, see "Determining Current Values".

Note: You cannot nest configuration files. This means that CONFIG is not a valid option inside a configuration file.

Scope of Precompiler Options

A precompilation unit is a file containing COBOL code and one or more embedded SQL statements. The options specified for a given precompilation unit affect only that unit; they have no effect on other units.

For example, if you specify HOLD_CURSOR=YES and RELEASE_CURSOR=YES for unit A but not unit B, SQL statements in unit A run with these HOLD_CURSOR and RELEASE_CURSOR values, but SQL statements in unit B run with the default values. However, the MAXOPENCURSORS setting that is in effect when you connect to Oracle stays in effect for the life of that connection.

The scope of an inline option is positional, not logical. That is, an inline option affects SQL statements that follow it in the source file, not in the flow of program logic. An option setting stays in effect until the end-of-file unless you re-specify the option.

Quick Reference

Table 14-2 is a quick reference to the Pro*COBOL options. Options marked with an asterisk can be entered inline.

Another handy reference is available online. To see the online display, just enter the Pro*COBOL command without options at your operating system prompt. The display gives the name, syntax, default value, and purpose of each option.


Notes:

There are some platform-specific options. For example, on byte-swapped platforms the option COMP5 governs the use of certain COMPUTATIONAL items. Check your system-specific Oracle manuals.

COMP5 is not supported on SPARC Solaris 64 bit Computers. Use COMP instead.


Table 14-2 Option List

SyntaxDefaultSpecifies

ASACC={YES | NO}

NO

If YES, use ASA carriage control for listing.

ASSUME_SQLCODE={YES | NO}

NO

If YES, assume SQLCODE variable exists.

AUTO_CONNECT={YES | NO}

NO

If YES, allow automatic connect to ops$ accounts before the first executable statement.

CLOSE_ON_COMMIT*

NO

If YES, close all cursors on COMMIT.

CONFIG=filename

(none)

Specifies name of user-defined configuration file.

CWH_SQL99={YES | NO}

YES

If YES, close held cursors on ROLLBACK (SQL standard behavior.)

DATE_FORMAT

LOCAL

Specifies date string format.

DBMS={NATIVE | V7 | V8}

NATIVE

Version-specific behavior of Oracle at precompile time.

DECLARE_SECTION

NO

If YES, DECLARE SECTION is required.

DEFINE=symbol *

(none)

Define a symbol used in conditional precompilation.

DYNAMIC

ORACLE

Specifies Oracle or ANSI dynamic semantics in SQL Method 4.

END_OF_FETCH

1403

End-of-fetch SQLCODE value.

ERRORS={YES | NO} *

YES

If YES, display errors on the terminal.

FIPS={YES | NO}

NO

If YES, ANSI/ISO extensions are flagged.

FORMAT={ANSI | TERMINAL | VARIABLE}

ANSI

Format of input file COBOL statements.

HOLD_CURSOR={YES | NO}*

NO

If YES, hold OraCursor (do not re-assign).

HOST={COBOL | COB74}

COBOL

COBOL version used in input file (COBOL 85 or COBOL 74).

[INAME=]filename

(none)

Name of input file.

INCLUDE=path*

(none)

Pathname for EXEC SQL INCLUDE files.

IRECLEN=integer

80

Record length of input file.

LITDELIM={APOST | QUOTE}

QUOTE

Delimiters for COBOL strings.

LNAME=filename

(none)

Name of listing file.

LRECLEN=integer

132

Record length of listing file.

LTYPE={LONG | SHORT | NONE} *

LONG

Type of listing.

MAXLITERAL=integer *

256

Maximum length of strings. (120 on IBM-proprietary S370 OS)

MAXOPENCURSORS=integer *

10

Maximum number of OraCursors cached (1).

MODE={ORACLE | ANSI}

ORACLE

If ANSI, follow the ANSI/ISO SQL standard.

NESTED={YES | NO}

YES

If YES, nested programs are supported.

NLS_LOCAL={YES | NO}

NO

If YES, use NCHAR semantics of previous Pro*COBOL releases.

[ONAME=]filename

iname.cob

Name of output file.

ORACA={YES | NO}*

NO

If YES, use ORACA communications area.

ORECLEN=integer

80

Record length of output file.

PAGELEN=integer

66

Lines for each page in listing.

PICX

CHARF

Datatype of PIC X COBOL variables.

PREFETCH

1

Speed up queries by pre-fetching a given number of rows.

RELEASE_CURSOR={YES | NO} *

NO

If YES, release OraCursor after execute.

SELECT_ERROR={YES | NO}*

YES

If YES, generate FOUND error on SELECT.

SQLCHECK={SEMANTICS | SYNTAX}*

SYNTAX

SQL checking level.

THREADS={YES | NO}

NO

Indicates a multithreaded application.

TYPE_CODE

ORACLE

Use Oracle or ANSI type codes for dynamic SQL method 4.

UNSAFE_NULL={YES | NO}

NO

If YES, unsafe null fetches are allowed (disables the ORA-01405 message).

USERID=username/password[@dbname]

(none)

Oracle username, password, and optional database.

VARCHAR={YES | NO}

NO

If YES, accept user-defined VARCHAR group items.

XREF={YES | NO}*

YES

If YES, generate symbol cross references in listing.


Using Pro*COBOL Precompiler Options

This section is organized for easy reference. It lists the Pro*COBOL precompiler options alphabetically and for each option gives its purpose, syntax, and default value. Usage notes that help you understand how the option works are also provided. Unless the usage notes say otherwise, the option can be entered on the command line, inline, or from a configuration file.

ASACC

Purpose

Specifies whether the listing file follows the ASA convention of using the first column in each line for carriage control.

Syntax

ASACC={YES | NO}

Default

NO

Usage Notes

Cannot be entered inline.

ASSUME_SQLCODE

Purpose

Instructs Pro*COBOL to presume that SQLCODE is declared whether or not it is declared in the program, or of the proper type.

Syntax

ASSUME_SQLCODE={YES | NO}

Default

NO

Usage Notes

Cannot be entered inline.

When DECLARE_SECTION=YES and ASSUME_SQLCODE=YES, SQLCODE can be declared outside a Declare Section.

When DECLARE_SECTION=YES and ASSUME_SQLCODE=NO, SQLCODE is recognized as the status variable if and only if at least one of the following criteria is satisfied:

  • It is declared with exactly the right datatype.

  • Pro*COBOL finds no other status variable. If Pro*COBOL finds a SQLSTATE declaration (of exactly the right type of course), or finds an include of a SQLCA, then it will not presume SQLCODE is declared.

When ASSUME_SQLCODE=YES, and when SQLSTATE and/or SQLCA are declared as status variables, Pro*COBOL presumes SQLCODE is declared whether or not it is declared or of the proper type.

AUTO_CONNECT

Purpose

Specifies whether your program connects automatically to the default user account.

Syntax

AUTO_CONNECT={YES | NO}

Default

NO

Usage Notes

Cannot be entered inline.

When AUTO_CONNECT=YES, as soon as Pro*COBOL encounters an executable SQL statement, your program tries to log on to Oracle automatically with the userid

<prefix><username>

where <prefix> is the value of the Oracle initialization parameter OS_AUTHENT_PREFIX (the default value is OPS$) and <username> is your operating system user or task name. In this case, you cannot override the default value for MAXOPENCURORS (10), even if you specify a different value on the command line.

When AUTO_CONNECT=NO (the default), you must use the CONNECT statement to logon to Oracle.

CHARSET_PICX

Purpose

Specifies the character set form used by PIC X variables used in select, insert, or update statements.

Syntax

CHARSET_PICX={NCHAR_CHARSET | DB_CHARSET }

Default

DB_CHARSET

Usage Notes

Can be used on the command line or in a configuration file, but not inline.

If CHARSET_PICX = NCHAR_CHARSET, the PIC X bind or define buffer is converted according to the server-side National Character Set. Possible performance impact might be seen when target column is CHAR. Similarly, if CHARSET_PICX = DB_CHARSET, the PIC X bind or define buffer is converted according to server-side Database Character Set. There can be some data loss when target column is NCHAR.

CHARSET_PICN

Purpose

Specifies the character set form used by PIC N variables used in select, insert, or update statements.

Syntax

CHARSET_PICN={NCHAR_CHARSET | DB_CHARSET }

Default

NCHAR_CHARSET

Usage Notes

Can be used on the command line or in a configuration file, but not inline.

If CHARSET_PICN = DB_CHARSET, the PIC N bind or define buffer is converted according to the server-side Database Character Set. There can be some data loss when target column is NCHAR. Similarly, if CHARSET_PICN = NCHAR_CHARSET, the PIC N bind or define buffer is converted according to server-side National Character Set. Possible performance impact might be seen when target column is CHAR.

CLOSE_ON_COMMIT

Purpose

Specifies whether or not all cursors declared without the WITH HOLD clause are closed on commit.

Syntax

CLOSE_ON_COMMIT={YES | NO}

Default

NO

Usage Notes

Can be used only on the command line or in a configuration file.

This option will only have an effect when a cursor is not coded using the WITH HOLD clause in a DECLARE CURSOR statement, since that will override both the new option and the existing behavior which is associated with the MODE option. If MODE is specified at a higher level than CLOSE_ON_COMMIT, then MODE takes precedence. For example, the defaults are MODE=ORACLE and CLOSE_ON_COMMIT=NO. If the user specifies MODE=ANSI on the command line, then any cursors not using the WITH HOLD clause will be closed on commit.

When CLOSE_ON_COMMIT=NO (when MODE=ORACLE), issuing a COMMIT or ROLLBACK will close only cursors that are declared using the FOR UPDATE clause or are referenced in a CURRENT OF clause. Other cursors are not affected by the COMMIT or ROLLBACK statement, remain open, if they are open already. However, when CLOSE_ON_COMMIT=YES (when MODE=ANSI), issuing a COMMIT or ROLLBACK closes all cursors.

For a further discussion of the precedence of this option see "Macro and Micro Options".

COMMON_PARSER

Purpose

Specifies that the SQL99 syntax for SELECT, INSERT, DELETE, UPDATE and body of the cursor in a DECLARE CURSOR statement will be supported.

Syntax

COMMON_PARSER={YES | NO}

Default

NO

Usage Notes

Can be entered in the command line.

CONFIG

Purpose

Specifies the name of a user configuration file.

Syntax

CONFIG=filename

Default

None

Usage Notes

Can be entered only on the command line.

Pro*COBOL can use a configuration file containing preset command-line options. However, you can specify any of several alternative files, called user configuration files. For more information, see "Entering Precompiler Options".

You cannot nest configuration files. Therefore, you cannot specify the option CONFIG in a configuration file.

DATE_FORMAT

Purpose

Species the string format in which dates are returned.

Syntax

DATE_FORMAT={ISO | USA | EUR | JIS | LOCAL | 'fmt' (default LOCAL)

Default

LOCAL

Usage Notes

Can only be entered on the command line or in a configuration file. The date strings are shown in the following table:

Table 14-3 Formats for Date Strings

Format NameAbbreviationDate Format

International Standards Organization

ISO

yyyy-mm-dd

USA standard

USA

mm/dd/yyyy

European standard

EUR

dd.mm.yyyy

Japanese Industrial Standard

JIS

yyyy-mm-dd

installation-defined

LOCAL

Any installation-defined form.


'fmt' is a date format model, such as "Month dd, yyyy". See Oracle Database SQL Language Reference for the list of date format model elements.

There is one restriction on the use of the DATE_FORMAT option: All compilation units to be linked together must use the same DATE_FORMAT value. An error occurs when there is a mismatch in the values of DATE_FORMAT across compilation units

DB2_ARRAY

Purpose

Based on this option, the precompiler activates the additional array insert/select syntax.

Syntax

DB2_ARRAY={YES |NO}

Default

NO

Usage Notes

If this option is set to NO, the Oracle precompiler syntax is supported, otherwise the DB2 insert/select array syntax is supported.

DBMS

Purpose

Specifies whether Oracle follows the semantic and syntactic rules of Oracle7 Database, Oracle8i, or the native version of Oracle (that is, the version to which your application is connected).

Syntax

DBMS={V7 | V8 | NATIVE}

Default

NATIVE

Usage Notes

Cannot be entered inline.

With the DBMS option you control the version-specific behavior of Oracle. When DBMS=NATIVE (the default), Oracle follows the semantic and syntactic rules of the native version of Oracle.

DECLARE_SECTION

Purpose

Specifies whether or not only declarations in a Declare Section are allowed as host variables.

Syntax

DECLARE_SECTION={YES | NO}

Default

NO

Usage Notes

Can be entered only on the command line or in a configuration file.

When MODE=ORACLE, use of the BEGIN DECLARE SECTION and END DECLARE SECTION statements are optional, starting with release 8.0 of Pro*COBOL. The DECLARE_SECTION option is provided for backward compatibility with previous releases. DECLARE_SECTION is a micro option of MODE.

This option allows the user to specify MODE=ORACLE together with DECLARE_SECTION=YES to get the same effect that previous releases provided when using MODE=ORACLE alone. (Only variables declared inside the DECLARE statements are allowed as host variables.) For a discussion of precedence of this option, see "Precedence of Option Values".

DEFINE

Purpose

Specifies a user-defined symbol that is used to include or exclude portions of source code during a conditional precompilation. For more information, see "Conditional Precompilations".

Syntax

DEFINE=symbol

Default

None

Usage Notes

If you enter DEFINE inline, the EXEC ORACLE statement takes the following form:

EXEC ORACLE DEFINE symbol END-EXEC.

DYNAMIC

Purpose

This micro option of MODE specifies the descriptor behavior in dynamic SQL Method 4.

Syntax

DYNAMIC={ORACLE | ANSI}

Default

ORACLE

Usage Notes

Cannot be entered inline by use of the EXEC ORACLE OPTION statement.

See the DYNAMIC option settings in "ANSI Dynamic SQL Precompiler Options".

END_OF_FETCH

Purpose

This micro option of MODE specifies which SQLCODE value is returned when an END-OF-FETCH condition occurs after execution of a SQL statement.

Syntax

END_OF_FETCH={100 | 1403}

Default

1403

Usage Notes

Can be entered only on the command line or in a configuration file.

END_OF_FETCH is a micro option of MODE. For further discussion, see "Macro and Micro Options".

If you specify MODE=ANSI in a configuration file, Pro*COBOL returns the SQLCODE value 100 at the END_OF_FETCH, overriding the default END_OF_FETCH=1403.

If you specify MODE=ANSI and END_OF_FETCH=1403 in the configuration file, then Pro*COBOL will return the SQLCODE value 1403 at the END_OF_FETCH.

If you specify MODE=ANSI in the configuration file and END_OF_FETCH=1403 on the command line, which has a higher precedence than your configuration file, Pro*COBOL will again return the SQLCODE value 1403 at the END_OF_FETCH.

ERRORS

Purpose

Specifies whether Pro*COBOL error messages are sent to the terminal and listing file or only to the listing file.

Syntax

ERRORS={YES | NO}

Default

YES

Usage Notes

When ERRORS=YES, error messages are sent to the terminal and listing file.

When ERRORS=NO, error messages are sent only to the listing file.

File_ID

Purpose

Denotes the unique identifier for the generated Cobol file. The generated files contain a unique number associated with the "SQLCTX" variable. The file_id option can be used to set the value of the SQLCTX variable. The option is useful while precompiling multiple source files, so that the user can ensure unique SQLCTX values associated with the different generated files.

Syntax

FILE_ID=Range is 0 to 65535

Default

0

Usage Notes

The file_id option can be used to directly assign values to "SQLCTX" variable in the generated Cobol file.

FIPS

Purpose

Specifies whether extensions to ANSI/ISO SQL are flagged (by the FIPS Flagger). An extension is any SQL element that violates ANSI/ISO format or syntax rules, except privilege enforcement rules.

Syntax

FIPS={YES | NO}

Default

NO

Usage Notes

When FIPS=YES, the FIPS Flagger issues warning (not error) messages if you use an Oracle extension to the Entry level of SQL-92 or use a feature of Entry level SQL-92 in a nonconforming manner.

The following extensions to ANSI/ISO SQL are flagged at precompile time:

  • Array interface including the FOR clause

  • SQLCA, ORACA, and SQLDA data structures

  • Dynamic SQL including the DESCRIBE statement

  • Embedded PL/SQL blocks

  • Automatic datatype conversion

  • DATE, COMP-3, NUMBER, RAW, LONG RAW, VARRAW, ROWID, and VARCHAR datatypes

  • ORACLE OPTION statement for specifying runtime options

  • EXEC TOOLS statements in user exits

  • CONNECT statement

  • TYPE and VAR datatype equivalencing statements

  • AT db_name clause

  • DECLARE...DATABASE, ...STATEMENT, and ...TABLE statements

  • SQLWARNING condition in WHENEVER statement

  • DO and STOP actions in WHENEVER statement

  • COMMENT and FORCE TRANSACTION clauses in COMMIT statement

  • FORCE TRANSACTION and TO SAVEPOINT clauses in ROLLBACK statement

  • RELEASE parameter in COMMIT and ROLLBACK statements

  • Optional colon-prefixing of WHENEVER...DO labels and of host variables in the INTO clause

FORMAT

Purpose

Specifies the format of COBOL statements.

Syntax

FORMAT={ANSI | TERMINAL | VARIABLE}

Default

ANSI

Usage Notes

Cannot be entered inline.

The format of input lines is system-dependent. Check your system-specific Oracle manuals, or your COBOL compiler.

When FORMAT=ANSI, the format of input lines conforms as much as possible to the current ANSI standard for COBOL. When FORMAT=TERMINAL, input lines can start in column 1. Example code in this book is in TERMINAL format. Use FORMAT=VARIABLE to allow Flexible B Area Length. See "Coding Areas" for a more complete description.

HOLD_CURSOR

Purpose

Specifies how the cursors for SQL statements and PL/SQL blocks are handled in the cursor cache.

Syntax

HOLD_CURSOR={YES | NO}

Default

NO

Usage Notes

You can use HOLD_CURSOR to improve the performance of your program. For more information, see Appendix C, "Performance Tuning".

When a SQL data manipulation statement is executed, its associated cursor is linked to an entry in the cursor cache. The cursor cache entry is in turn linked to an Oracle private SQL area, which stores information needed to process the statement. HOLD_CURSOR controls what happens to the link between the cursor and cursor cache.

When HOLD_CURSOR=NO, after Oracle executes the SQL statement and the cursor is closed, Pro*COBOL marks the link as reusable. The link is reused as soon as the cursor cache entry to which it points is needed for another SQL statement. This frees memory allocated to the private SQL area and releases parse locks.

When HOLD_CURSOR=YES, the link is maintained; Pro*COBOL does not reuse it. This is useful for SQL statements that are executed often because it speeds up subsequent executions and there is no need to re-parse the statement or allocate memory for an Oracle private SQL area.

For inline use with implicit cursors, set HOLD_CURSOR before executing the SQL statement. For inline use with explicit cursors, set HOLD_CURSOR before opening the cursor.

For information showing how the HOLD_CURSOR and RELEASE_CURSOR options interact, see Appendix C, "Performance Tuning", specifically Table C-1, "HOLD_CURSOR and RELEASE _CURSOR Interactions".

HOST

Purpose

Specifies the host language to be used.

Syntax

HOST={COB74 | COBOL}

Default

COBOL

Usage Notes

Cannot be entered inline.

COB74 refers to the 1974 version of ANSI-approved COBOL. COBOL refers to the 1985 version. Other values might be available on your platform.

IMPLICIT_SVPT

Purpose

Controls whether an implicit savepoint is taken prior to the start of a new batched insert.

Syntax

implicit_svpt={YES|NO}

Default

NO

Usage Notes

If yes, a savepoint is taken prior to the start of a new batch of rows. If an error occurs on the insert, an implicit "rollback to savepoint" is executed. This option exists for DB2 compatibility, the obvious downside being the extra round-trip.

If no, there is no implicit savepoint taken. If an error occurs on the buffered insert, then it is reported back to the application, but no rollback is executed.

INAME

Purpose

Specifies the name of the input file.

Syntax

INAME=filename

Default

None

Usage Notes

Cannot be entered inline.

All input file names must be unique at precompilation time.

When specifying the name of your input file on the command line, the keyword INAME is optional. For example, in Pro*COBOL, you can specify myprog.pco instead of INAME=myprog.pco.

You need not use a file extension when specifying INAME unless the extension is nonstandard. On the UNIX platform, Pro*COBOL assumes the default input file extension pco.

INCLUDE

Purpose

Specifies a directory path for EXEC SQL INCLUDE files. It only applies to operating systems that use directories.

Syntax

INCLUDE=path

Default

Current directory

Usage Notes

Typically, you use INCLUDE to specify a directory path for the SQLCA and ORACA files. Pro*COBOL searches first in the current directory, then in the directory specified by INCLUDE, and finally in a directory for standard INCLUDE files. Hence, you need not specify a directory path for standard files such as the SQLCA and ORACA.

You must still use INCLUDE to specify a directory path for nonstandard files unless they are stored in the current directory. You can specify more than one path on the command line, as follows:

... INCLUDE=path1 INCLUDE=path2 ... 

Pro*COBOL searches first in the current directory, then in the directory named by path1, then in the directory named by path2, and finally in the directory for standard INCLUDE files.

Note: Pro*COBOL looks for a file in the current directory first—even if you specify a directory path. Therefore, if the file you want to INCLUDE resides in another directory, make sure no file with the same name resides in the current directory.

The syntax for specifying a directory path is system-specific. Follow the conventions of your operating system.

IRECLEN

Purpose

Specifies the record length of the input file.

Syntax

IRECLEN=integer

Default

80

Usage Notes

Cannot be entered inline.

The value you specify for IRECLEN should not exceed the value of ORECLEN. The maximum value allowed is system-dependent.

LITDELIM

Purpose

The LITDELIM option specifies the delimiters for string constants and literals in the COBOL code generated by Pro*COBOL.

Syntax

LITDELIM={APOST | QUOTE}

Default

QUOTE

Usage Notes

When LITDELIM=APOST, Pro*COBOL uses apostrophes when generating COBOL code. If you specify LITDELIM=QUOTE, quotation marks are used, as in

     CALL "SQLROL" USING SQL-TMP0. 

In SQL statements, you must use quotation marks to delimit identifiers containing special or lowercase characters, as in

     EXEC SQL CREATE TABLE "Emp2" END-EXEC. 

but you must use apostrophes to delimit string constants, as in

     EXEC SQL SELECT ENAME FROM EMP WHERE JOB = 'CLERK' END-EXEC.

Regardless of which delimiters are used in the Pro*COBOL source file, Pro*COBOL generates the delimiters specified by the LITDELIM value.

LNAME

Purpose

Specifies a nondefault name for the listing file.

Syntax

LNAME=filename

Default

Input

Usage Notes

Cannot be entered inline.

By default, the listing file is written to the current directory.

LRECLEN

Purpose

Specifies the record length of the listing file.

Syntax

LRECLEN=integer

Default

132

Usage Notes

Cannot be entered inline.

The value of LRECLEN can range from 80 through 132. If you specify a value below the range, 80 is used instead. If you specify a value above the range, an error occurs. LRECLEN should exceed IRECLEN by at least 8 to allow for the insertion of line numbers.

LTYPE

Purpose

Specifies the listing type.

Syntax

LTYPE={LONG | SHORT | NONE}

Default

LONG

Usage Notes

Cannot be entered inline.

Table 14-4 Types of Listings

Listing TypesDescription

LTYPE=LONG

input lines appear in the listing file.

LTYPE=SHORT

input lines do not appear in the listing file.

LTYPE=NONE

no listing file is created.


MAX_ROW_INSERT

Purpose

Controls the number of rows that need to be buffered before executing the INSERT statement.

Syntax

max_row_insert={0...1000}

Default

0

Usage Notes

Any number greater than zero enables buffered insert feature and buffers that many rows before executing the INSERT statement.

MAXLITERAL

Purpose

Specifies the maximum length of string literals generated by Pro*COBOL so that compiler limits are not exceeded. For example, if your compiler cannot handle string literals longer than 132 characters, you can specify MAXLITERAL=132 on the command line.

Syntax

MAXLITERAL=integer

Default

1024

Usage Notes

The maximum value of MAXLITERAL is compiler-dependent. The default value is language-dependent, but you may have to specify a lower value. For example, some COBOL compilers cannot handle string literals longer than 132 characters, so you would specify MAXLITERAL=132.

Strings that exceed the length specified by MAXLITERAL are divided during precompilation, then recombined (concatenated) at run time.

You can enter MAXLITERAL inline but your program can set its value just once, and the EXEC ORACLE statement must precede the first EXEC SQL statement. Otherwise, Pro*COBOL issues a warning message, ignores the extra or misplaced EXEC ORACLE statement, and continues processing.

MAXOPENCURSORS

Purpose

Specifies the number of concurrently open cursors that Pro*COBOL tries to keep cached.

Syntax

MAXOPENCURSORS=integer

Default

10

Usage Notes

You can use MAXOPENCURSORS to improve the performance of your program. For more information, see Appendix C, "Performance Tuning".

When precompiling separately, use MAXOPENCURSORS as described in "Separate Precompilations".

MAXOPENCURSORS specifies the initial size of the SQLLIB cursor cache.

When an implicit statement is executed and HOLD_CURSOR=NO, or an explicit cursor is closed, the cursor entry is marked as reusable. If this statement is issued again and the cursor entry has not been used for another statement, it is reused.

If a new cursor is needed and the number of cursors allocated is less than MAXOPENCURSORS, then the next one in the cache is allocated. Once MAXOPENCCURSORS has been exceeded, Oracle first tries to reuse a previous entry. If there are no free entries, then an additional cache entry is allocated. Oracle continues to do this until the program runs out of memory or the database parameter OPEN_CURSORS is exceeded.

During normal processing, when using HOLD_CURSOR=NO and RELEASE_CURSOR=NO (the default), it is advisable to set MAXOPENCURSORS to no more than 6 less than the database parameter OPEN_CURSORS to allow for the cursors used by the data dictionary to process statements.

As your program's need for concurrently open cursors grows, you might want to re-specify MAXOPENCURSORS to match the need. A value of 45 to 50 is not uncommon, but remember that each cursor requires another private SQL area in the user process memory space. The default value of 10 is adequate for most programs.

MODE

Purpose

This macro option specifies whether your program observes Oracle practices or complies with the current ANSI SQL standard.

Syntax

MODE={ANSI | ISO | ANSI14 | ISO14 | ANSI13 | ISO13 | ORACLE}

Default

ORACLE

Usage Notes

Cannot be entered inline.

The following pairs of MODE values are equivalent: ANSI and ISO, ANSI14 and ISO14, ANSI13 and ISO13.

When MODE=ORACLE (the default), your embedded SQL program observes Oracle practices.

When MODE={ANSI14 | ANSI13}, your program complies closely with the current ANSI SQL standard.

When MODE=ANSI, your program complies fully with the ANSI standard and the following changes go into effect:

  • You cannot open a cursor that is already open or CLOSE a cursor that is already closed. (When MODE=ORACLE, you can reOPEN an open cursor to avoid re-parsing.)

  • No error message is issued if Oracle assigns a truncated column value to an output host variable.

When MODE={ANSI | ANSI14}, a 4-byte integer variable named SQLCODE or a 5-byte character variable named SQLSTATE must be declared. For more information, see "Error Handling Alternatives".

NESTED

Purpose

Indicates whether GLOBAL clauses in nested programs are to be generated. If the compiler supports nested programs, use YES as the value of NESTED.

Syntax

NESTED={YES | NO}

Default

YES

Usage Notes

Cannot be entered inline.

NLS_LOCAL

Purpose

The NLS_LOCAL option determines whether Globalization Support (formerly called NLS) character conversions are performed by the Pro*COBOL runtime library or by the Oracle Server.

Syntax

NLS_LOCAL={YES | NO}

Default

NO

Usage Notes

Cannot be entered inline.

This option is for use when passing National Character Set variables to and from the server.

When NLS_LOCAL=YES, the runtime library (SQLLIB) locally performs blank-padding and blank-stripping for host variables that have multibyte Globalization Support datatypes. Continue to use this value only for Pro*COBOL applications written for releases before releases 8.0.

When NLS_LOCAL=YES, because dynamic SQL statements are not processed at precompile time, this option has no effect on dynamic SQL statements.

Also, when NLS_LOCAL=YES, columns storing multibyte Globalization Support data cannot be used in embedded data definition language (DDL) statements. This restriction cannot be enforced when precompiling, so the use of these column types within embedded DDL statements results in an execution error rather than a precompile error.

When NLS_LOCAL=NO, blank-padding and blank-stripping operations are performed by the Oracle Server for host variables that have multibyte Globalization Support datatypes. Use for all new release 8.0, or later, applications.

The environment variable NLS_NCHAR specifies the character set used for National Character Set data. (NCHAR, NVARCHAR2, NCLOB). If it is not specified, the character set defined or defined indirectly by NLS_LANG will be used. See: the NLS_LANG section in the Oracle Database Globalization Support Guide for details.

ONAME

Purpose

Specifies the name of the output file.

Syntax

ONAME=filename

Default

System dependent

Usage Notes

Cannot be entered inline.

Use this option to specify the name of the output file, where the name differs from that of the input file. For example, if you issue

procob INAME=my_test

the default output filename is my_test.cob. If you want the output filename to be my_test_1.cob, issue the command

procob INAME=my_test ONAME=my_test_1.cob 

Note that you should add the .cob extension to files specified using ONAME. There is no default extension with the ONAME option.

Attention: Oracle recommends that you not let the output filename default, but rather name it explicitly using ONAME.

ORACA

Purpose

Specifies whether a program can use the Oracle Communications Area (ORACA).

Syntax

ORACA={YES | NO}

Default

NO

Usage Notes

When ORACA=YES, you must place the INCLUDE ORACA statement in your program.

ORECLEN

Purpose

Specifies the record length of the output file.

Syntax

ORECLEN=integer

Default

80

Usage Notes

Cannot be entered inline.

The value you specify for ORECLEN should equal or exceed the value of IRECLEN. The maximum value allowed is system-dependent.

OUTLINE

Purpose

Indicates that the outline SQL file needs to be generated for the SQL statements.

Syntax

outline={yes | no | category_name}

Default

no

Usage Notes

The outline SQL file should be in the DEFAULT category if the value is yes and the generated outline format is

DEFAULT_<filename>_<filetype>_<sequence_no>

If the category name is mentioned, then the SQL file should be generated in the category mentioned. The generated outline format for this is

<category_name>_<filename>_<filetype>_<sequence_no>

The outline SQL file is not generated if the value is no.

Semantic check should be full when this option is turned on, which means option sqlcheck=full/semantics. If sqlcheck=syntax/limited/none, then error will be generated.

OUTLNPREFIX

Purpose

Controls the generation of the outline names.

Syntax

outlnprefix={none | prefix_name}

Default

no

Usage Notes

If outlnprefix=prefix_name, then the outline format

<category_name>_<filename>_<filetype>

is replaced with <prefix_name> for the outline names.

If the length of the outline name exceeds 30 bytes, then this option is helpful for the user who can just specify the prefix name.

If outlnprefix=none, then the outline names are generated by the system. The generated format is

<category_name>_<filename>_<filetype>_<sequence_no>

Semantic check should be full when this option is turned on, which means option sqlcheck=full/semantics. If sqlcheck=syntax/limited/none, and/or outline=false, then error will be generated.

PAGELEN

Purpose

Specifies the number of lines for each physical page of the listing file.

Syntax

PAGELEN=integer

Default

66

Usage Notes

Cannot be entered inline. The maximum value allowed is system-dependent.

PICN_ENDIAN

Purpose

Maintains platform endianness (little endian for Linux and Windows; big endian for Solaris) in PIC N variables.

Syntax

picn_endian={BIG | OS}

Default

BIG

Usage Notes

If picn_endian=big, then PIC N variables are bound with character set ID AL16UTF16.

If picn_endian=os then PIC N variables are bound with character set ID UCS2.

The default value for this option is "big" to preserve the current behavior. This option is ignored if NLS_NCHAR is not AL16UTF16.

Character set form for PIC N variables can be set by using the existing Pro*Cobol command line option: charset_picn={nchar_charset | db_charset}

PICX

Purpose

Specifies the default datatype of PIC X variables.

Syntax

PICX={CHARF | VARCHAR2}

Default

CHARF

Usage Notes

Can be entered only on the command line or in a configuration file.

Starting in Pro*COBOL 8.0, the default datatype of PIC X, N, or G variables was changed from VARCHAR2 to CHARF. PICX is provided for backward compatibility.

This new default behavior is consistent with the normal COBOL move semantics. Note that this is a change in behavior for the case where you are inserting a PIC X variable (with MODE=ORACLE) into a VARCHAR2 column. Any trailing blanks which had formerly been trimmed will be preserved. Note also, that the new default lessens the occurrence of the following anomaly: Using a PIC X bind variable initialized with trailing blanks in a WHERE clause would never match a value with the same number of trailing blanks which was stored in a char column because the bind variable's trailing blanks were stripped before the comparison.

When PICX=VARCHAR2, Oracle treats local CHAR variables in a PL/SQL block like variable-length character values. When PICX=CHARF, however, Oracle treats the CHAR variables like ANSI-compliant, fixed-length character values. See "Default for PIC X" for an extensive discussion.

PREFETCH

Purpose

Use this option to speed up queries by pre-fetching a given number of rows.

Syntax

PREFETCH=integer

Default

1

Usage Notes

Can be used in a configuration file or on the command-line. The value of the integer is used for execution of all queries using explicit cursors, subject to the rules of precedence.

When used in-line it must be placed before OPEN statements with explicit cursors. Then the number of rows pre-fetched when that OPEN is done is determined by the last in-line PREFETCH option in effect.

The PREFETCH default is 1. To turn off prefetching, use PREFETCH=0 on the command line.

Prefetching is turned off when LONG or LOB columns are being accessed. PREFETCH is used to enhance the performance of single row fetches. PREFETCH values have no effect when doing array fetches, regardless of which value is assigned.

There is no single perfect prefetch number that can be used to assist all the fetches in an application.

Therefore, when using the PREFETCH option, you should test different values to give a general improvement across all statements in the program. Note that if certain statements need to be tuned individually, the PREFETCH option can be specified in line using EXEC ORACLE OPTION. Note that this will affect all fetch statements that follow the command in your program. Select the appropriate prefetch number to enhance the performance of any particular FETCH statement. To achieve this individual prefetch count, you should use the inline prefetch option. (Rather than from the command line.)

The maximum value is 9999. See "The PREFETCH Precompiler Option" for further discussion.

RELEASE_CURSOR

Purpose

Specifies how the cursors for SQL statements and PL/SQL blocks are handled in the cursor cache.

Syntax

RELEASE_CURSOR={YES | NO}

Default

NO

Usage Notes

You can use RELEASE_CURSOR to improve the performance of your program. For more information, see .

When a SQL data manipulation statement is executed, its associated cursor is linked to an entry in the cursor cache. The cursor cache entry is in turn linked to an Oracle private SQL area, which stores information needed to process the statement. RELEASE_CURSOR controls what happens to the link between the cursor cache and private SQL area.

When RELEASE_CURSOR=YES, after Oracle executes the SQL statement and the cursor is closed, Pro*COBOL immediately removes the link. This frees memory allocated to the private SQL area and releases parse locks. To make sure that associated resources are freed when you CLOSE a cursor, you must specify RELEASE_CURSOR=YES.

When RELEASE_CURSOR=NO, the link is maintained. Pro*COBOL does not reuse the link unless the number of open cursors exceeds the value of MAXOPENCURSORS. This is useful for SQL statements that are executed often because it speeds up subsequent executions. There is no need to re-parse the statement or allocate memory for an Oracle private SQL area.

For inline use with implicit cursors, set RELEASE_CURSOR before executing the SQL statement. For inline use with explicit cursors, set RELEASE_CURSOR before opening the cursor.

Note that RELEASE_CURSOR=YES overrides HOLD_CURSOR=YES. For information showing how these two options interact, see Appendix C, "Performance Tuning", specifically Table C-1, "HOLD_CURSOR and RELEASE _CURSOR Interactions".

RUNOUTLINE

Purpose

Provides the developer with the option of executing "create outline" statements either by using precompiler or by the developer manually at a later time.

Syntax

runoutline={yes | no}

Default

no

Usage Notes

If runoutline=yes, then the generated 'create outline' statements are executed by the precompiler/translator at the end of a successful precompilation.

The outline option should be set to true or category_name when runoutline is used. Semantic check should be full when this option is turned on, which means option sqlcheck=full/semantics. If sqlcheck=syntax/limited/none, then error will be generated.

SELECT_ERROR

Purpose

Specifies whether your program generates an error when a SELECT statement returns more than one row or more rows than a host array can accommodate.

Syntax

SELECT_ERROR={YES | NO}

Default

YES

Usage Notes

When SELECT_ERROR=YES, an error is generated if a single-row select returns too many rows or an array select returns more rows than the host array can accommodate.

When SELECT_ERROR=NO, no error is generated when a single-row select returns too many rows or when an array select returns more rows than the host array can accommodate.

Whether you specify YES or NO, a random row is selected from the table. To ensure a specific ordering of rows, use the ORDER BY clause in your SELECT statement. When SELECT_ERROR=NO and you use ORDER BY, Oracle returns the first row, or the first n rows if you are selecting into an array. When SELECT_ERROR=YES, whether or not you use ORDER BY, an error is generated if too many rows are returned.

SQLCHECK

Purpose

Specifies the type and extent of syntactic and semantic checking..

When SQLCHECK=SEMANTICS or FULL, the SQL statements are packaged/bundled into an IDL objects using a generic grammar during parsing. The generic grammar will not try to understand the SQL syntax, it can only identify the host variables, indicator variables, and the possible SQL identifiers. During the semantic phase, the validity of the host and indicator variables are checked in the same manner it is now being done for SQL. The semantics like the table name ,column names,types will be checked in the same way it is now being handled for SQL.

The new unified parser:

  1. Precompiles all the existing precompiler applications.

  2. Supports the following SQL statements completely (all clauses of these SQL statements):

    1. SELELCT statement

    2. INSERT statement

    3. DELETE statement

    4. UPDATE statement

    5. Body of the cursor in a DECLARE CURSOR statement

Syntax

SQLCHECK={SEMANTICS | FULL | SYNTAX | LIMITED}

Default

SYNTAX

Usage Notes

The values SEMANTICS and FULL are equivalent, as are the values SYNTAX and LIMITED.

Pro*COBOL can help you debug a program by checking the syntax and semantics of embedded SQL statements and PL/SQL blocks. Any errors found are reported at precompile time.

You control the level of checking by entering the SQLCHECK option inline or on the command line, or both inline and on the command line. However, the level of checking you specify inline cannot be higher than the level you specify (or accept by default) on the command line.

Pro*COBOL generates an error when PL/SQL reserved words are used in SQL statements, even though the SQL statements are not themselves PL/SQL. If a PL/SQL reserved word must be used as an identifier, you can enclose it in double-quotes (").

When SQLCHECK=SEMANTICS, Pro*COBOL checks th46e syntax and semantics of

  • Data manipulation statements such as INSERT and UPDATE

  • PL/SQL blocks

However, Pro*COBOL checks only the syntax of remote data manipulation statements (those using the AT db_name clause).

Pro*COBOL gets the information for a semantic check from embedded DECLARE TABLE statements or, if you specify the option USERID, by connecting to Oracle and accessing the data dictionary. You need not connect to Oracle if every table referenced in a data manipulation statement or PL/SQL block is defined in a DECLARE TABLE statement.

If you connect to Oracle but some information cannot be found in the data dictionary, you must use DECLARE TABLE statements to supply the missing information. During precompilation, a DECLARE TABLE definition overrides a data dictionary definition if they conflict.

Specify SQLCHECK=SEMANTICS when precompiling new programs. If you embed PL/SQL blocks in a host program, you must specify SQLCHECK=SEMANTICS and the option USERID.

When SQLCHECK=SEMANTICS or FULL, the SQL statements are first locally parsed. The verification of the host and indicator variables, and checking for the validity of SQL identifiers is done by using embedded DECLARE TABLE statement or by connecting to server when userid is specified in command line. Now the parsing is done twice when SQLCHECK = SEMANTICS or FULL once by the precompiler and once by the PL/SQL. When a new syntax is made available by SQL, the precompiler fails on the new syntax before calling PL/SQL interfaces if the local SQL grammar is not updated to accept the new syntax.

When SQLCHECK=SYNTAX, Pro*COBOL checks the syntax of data manipulation statements. The SQL statements are locally parsed. With this command line option, the precompiler does not verify the table name or column names. When SQLCHECK=SYNTAX, the syntax of the SQL statements is checked by using the client side SQL interface.

No semantic checking is done. DECLARE TABLE statements are ignored and PL/SQL blocks are not allowed. When checking data manipulation statements, Pro*COBOL uses Oracle syntax rules, which are downwardly compatible. Specify SQLCHECK=SYNTAX when migrating your precompiled programs.

Table 14-5 summarizes the checking done by SQLCHECK. For more information about syntactic and semantic checking, see Appendix D, "Syntactic and Semantic Checking".

Table 14-5 Checking Done by SQLCHECK

-SQLCHECK=SEMANTICS-SQLCHECK=SYNTAX-

-

Syntax

Semantics

Syntax

Semantics

DML

X

X

X

-

Remote DML

X

-

X

-

PL/SQL

X

X

-

-


Restrictions of Unified Parser

The restrictions of unified parser for Pro*COBOL are:

  • Pro*COBOL does not support variables without a ':' (colon).

  • Define tables cannot be used. In CSF mode, plsql fails when declare table statement is passed to plsql.

  • The following example fails if sqlcheck=syntax and common_parser=yes is used:

    select ename into :empname from emp@dblink;
    

    In earlier versions, only local parsing is done when sqlcheck=syntax is used. But now when sqlcheck=syntax and common_parser=yes, the statement is just bundled and sent to pcisyn(). PLSQL fails if connection is not there when dblinks are used.

    The above statement can be precompiled with:

    sqlcheck=full userid=<userid> common_parser=yes
    
  • Error handling for insert does not follow the usual sequence. Consider the following statement where XYZ is a group item.

    insert into emp (empno, ename) values (:XYZ)
    

    PLSQL does not allow group items or structures while doing syntax check for insert statements (restriction from PLSQL.). It expects that the group item be broken into the individual elements for inserts. So the precompiler should expand the above statement to insert into emp (empno, ename) values (:b1,:b2) in the syntax phase itself.

    This expansion is not possible in syntax phase. Therefore, pcisyn() is not called in syntax phase of precompiler the way it is done for other statements. The statement is deferred till semantic phase of precompiler for insert statement only. The net effect is that the error messages might not be following the usual sequence. For example:

    EXEC SQL insert into emp (empno, ename) alues (:XYZ) END-EXEC.
                                             ^^^^^ syntax error at 'alues'
     EXEC SQL select ename into :empname fro emp END-EXEC.  
                                         ^^^ syntax error at 'fro'
    

    Ideally error sequence should be as follows:

    syntax error at 'alues' in INSERT
    syntax error at 'fro' in SELECT
    

    Because of the restrictions discussed earlier, the error sequence will be:

    syntax error at 'fro' in SELECT
    syntax error at 'alues' in INSERT
    

    Note:

    The line numbers will be there in the reported errors. Therefore, Pro*Cobol programmers can identify the line very easily, even though it is not in the order used in the program.

STMT_CACHE

Purpose

Denotes the Statement cache size for the dynamic SQL statements.

Syntax

STMT_CACHE = Range is 0 to 65535

Default

0

Usage Notes

The stmt_cache option can be set to hold the anticipated number of distinct dynamic SQL statements in the application.

TYPE_CODE

Purpose

This micro option of MODE specifies whether ANSI or Oracle datatype codes are used in ANSI dynamic SQL method 4. Its setting is the same as the setting of MODE option.

Syntax

TYPE_CODE={ORACLE | ANSI}

Default

ORACLE

Usage Notes

Cannot be entered inline.

See the possible option settings inTable 10-3.

UNSAFE_NULL

Purpose

Specifying UNSAFE_NULL=YES prevents generation of ORA-01405 messages when fetching NULLs without using indicator variables.

Syntax

UNSAFE_NULL={YES | NO}

Default

NO

Usage Notes

Cannot be entered inline.

The UNSAFE_NULL=YES is allowed only when MODE=ORACLE.

The UNSAFE_NULL option has no effect on host variables in an embedded PL/SQL block. You must use indicator variables to avoid ORA-01405 errors.

When UNSAFE_NULL=YES, no error is returned if a SELECT or FETCH statement selects a NULL, and there is no indicator variable associated with the output host variable. When UNSAFE_NULL=NO, selecting or fetching a NULL column or expression into a host variable that has no associated indicator variable causes an error (SQLSTATE is 22002; SQLCODE is ORA-01405).

USERID

Purpose

Specifies an Oracle username and password.

Syntax

USERID=username/password[@dbname]

Default

None

Usage Notes

Cannot be entered inline.

When SQLCHECK=SEMANTICS, if you want Pro*COBOL to get needed information by connecting to Oracle and accessing the data dictionary, you must also specify USERID. The database alias is optional. Do not enter the brackets.

VARCHAR

Purpose

The VARCHAR option instructs Pro*COBOL to treat the COBOL group item described in Chapter 5, "Embedded SQL" as a VARCHAR datatype.

Syntax

VARCHAR={YES | NO}

Default

NO

Usage Notes

Cannot be entered inline.

When VARCHAR=YES, the implicit group item described in Chapter 5, "Embedded SQL" is accepted as a VARCHAR external datatype with a length field and a string field.

When VARCHAR=NO, Pro*COBOL does not accept the implicit group items as VARCHAR external datatypes.

XREF

Purpose

Specifies whether a cross-reference section is included in the listing file.

Syntax

XREF={YES | NO}

Default

YES

Usage Notes

When XREF=YES, cross references are included for host variables, cursor names, and statement names. The cross references show where each object is defined and referenced in your program.

When XREF=NO, the cross-reference section is not included.

PKOݴɴPKFJOEBPS/pcoawin.htm< Pro*COBOL for Windows

F Pro*COBOL for Windows

This section provides an overview of building Oracle database applications with Pro*COBOL Release 9.2 for Windows operating systems.

This section contains these topics:

Compiling and Linking Pro*COBOL Applications

Pro*COBOL supports the MERANT Micro Focus NetExpress version 4.0 for 32-bit Windows 2000. This section describes how to compile and link Pro*COBOL applications using the MERANT Micro Focus compiler.

You can build and execute a MERANT Micro Focus COBOL application in two ways:

In each of these the COBSQL utility may be used with the following advantages:

How to Use the IDE

A program generated by Pro*COBOL can be compiled and executed from within the MERANT Micro Focus NetExpress IDE. Simply add the .cbl file generated by Pro*COBOL to a Net Express project. To avoid potential inconsistencies when calling routines in the Oracle libraries the program should be compiled using the directive:

MAKESYN "COMP-5" = "COMP"

This directive can be specified in the build setting for the source file, the project settings or through a $SET line at the start of the source file. When you select Rebuild or Rebuild All the IDE generates an executable ready to Run or Animate.

How to Use the Animator Products

Programs can be compiled and executed from within the MERANT Micro Focus COBOL debugger, Animator V2.

To avoid potential inconsistencies when calling routines in the Oracle libraries, select the menu option Compiler Directives, and enter:

This step is required because MERANT Micro Focus COBOL stores binary numbers in Big Endian format. Oracle libraries expect binary numbers to be stored in Little Endian format (machine format).

MAKESYN "COMP-5" = "COMP"

The COBOL and CBLLINK Commands

COBOL and CBLLINK can be used to build programs in two ways, depending on whether the Pro*COBOL runtime is to be statically linked or accessed through a DLL at runtime.

For dynamic linking, the commands are:

 COBOL sample1 /MAKESYN"COMP-5"="COMP";
 CBLLINK sample1

For static linking, the commands are:

 COBOL sample1 /LITLINK /MAKESYN"COMP-5"="COMP";
 CBLLINK sample1 ORACLE_BASE\ORACLE_HOME\precomp\lib\orasql11.lib

The previous commands produce sample1.exe, which can be executed like any other Windows 2000 program.


Note:

MERANT Micro Focus COBOL must be installed on the same system as Pro*COBOL to successfully execute the file.

The COBSQL Command

COBSQL can be used to simplify preprocessing and debugging. To use COBSQL, specify the following directive to the COBOL compiler:

PREPROCESS(COBSQL) COBSQLTYPE=ORACLE8 ENDP

or the short form:

P(COBSQL) CSQLT=ORA8 ENDP

COBSQLTYPE should be set to ORACLE or ORA for versions of Pro*COBOL prior to release 8.0. The directive may be set with a $SET line at the start of the source file, on the COBOL command line, in program build settings or project settings for NetExpress, or with SQL compiler directives settings for Animator. At compile time, COBSQL runs Pro*COBOL as a background task and passes its output to the COBOL compiler together with additional information required to enable Animator to track execution using the .pco file rather than .cbl file.

When using COBSQL there is no need to deal directly with the .cbl file. Instead, add the .pco file to a NetExpress project, or open it with Animator.

Sample Programs

Oracle provides sample programs to demonstrate the use of Pro*COBOL with Oracle database features. See "Sample Files" for a listing of these programs.

This section describes how to use the basic precompiling, compiling, and linking commands to build the sample programs. This section also describes the preparations required for running the Pro*COBOL sample programs.

Building the Demonstration Table

To run the Pro*COBOL sample programs, you must have a database account with the username scott and the password tiger. If this account does not exist on your database, create one before running the sample programs.

The scott account must contain the emp and dept tables. If the account does not contain these tables, use the demobld.sql script to create them.

To run the demobld.sql script:

  1. Start SQL*Plus.

  2. Connect to the database as username scott with password tiger.

  3. Run the demobld.sql script. For example:

    SQL> @ORACLE_BASE\ORACLE_HOME\sqlplus\demo\demobld.sql
    

Building the Sample Programs

Pro*COBOL supplies the makeit.bat file which is listed in the next section, for building a MERANT Micro Focus COBOL sample file:

For release 9.2.0, the batch files are located in ORACLE_BASE\ORACLE_HOME \precomp\demo\procob2.

To build the sample programs:

  1. Run the batch files with any sample file. Do not include the file extension. For example:

    C:\ORACLE\ORA90\PRECOMP\DEMO\PROCOB2> makeit sample1
    
  2. Ensure that all paths and file names reflect the configuration of your system, if you encounter errors when building a sample program.

The commands to run the sample programs assume that the following are the current working directory:

ORACLE_BASE\ORACLE_HOME \precomp\demo\procob2 directory for release 9.2.0

You may need to modify the sample link script to reflect the configuration of your system. See "Compiling and Linking Pro*COBOL Applications" for more information.

The makeit.bat for release 9.2.0 contains the following:

procob iname=%1.pco ireclen=132 
cobol %1 /anim /litlink makesyn "COMP-5" = "COMP"; 
cbllink %1 /M%1 ORACLE_BASE\ORACLE_HOME\precomp\lib\orasql11.lib

Sample Files

The Pro*COBOL sample files listed in Table F-1 are located in the ORACLE_BASE\ORACLE_HOME\precomp\demo\procob2 (release 9.2.0) directory. The SQL scripts are located in the ORACLE_BASE\ORACLE_HOME\precomp\demo\sql directory.

Table F-1 Pro*COBOL Sample Programs

Sample ProgramDescription

sample1.pco

Simple query

sample2.pco

Cursor operations

sample3.pco

Host tables

sample4.pco

Datatype equivalence

sample6.pco

Dynamic SQL Method 1

sample7.pco

Dynamic SQL Method 2

sample8.pco

Dynamic SQL Method 3

sample9.pco

Stored procedure call

calldemo.sql

Stored procedure call

sample10.pco

Dynamic SQL Method 4

sample11.pco

Cursor variable operations

sample11.sql

Cursor variable operations

sample12.pco

Dynamic SQL Method 4 using ANSI dynamic SQL

sample13.pco

Nested program

sampleco.pco

Simple query and insert

sample14.pco

Host table x (release 8.1.6 and on)

lobdemo1.pco

LOB datatypes (release 8.1.6 and on)

lobdemo1.sql

LOB datatypes (release 8.1.6 and on)


PKO<<PKFJOEBPS/pcoadtun.htm\u Performance Tuning

C Performance Tuning

This appendix shows you some simple, easy-to-apply methods for improving the performance of your applications. Using these methods, you can often reduce processing time by 25 percent or more. Topics are:

Causes of Poor Performance

One cause of poor performance is high Oracle communication overhead. Oracle must process SQL statements one at a time. Thus, each statement results in another call to Oracle and higher overhead. In a networked environment, SQL statements must be sent over the network, adding to network traffic. Heavy network traffic can slow down your application significantly.

Another cause of poor performance is inefficient SQL statements. Because SQL is so flexible, you can get the same result using two different statements. Using one statement might be less efficient. For example, the following two SELECT statements return the same rows (the name and number of every department having at least one employee):

     EXEC SQL SELECT DNAME, DEPTNO 
         FROM DEPT 
         WHERE DEPTNO IN (SELECT DEPTNO FROM EMP)
     END-EXEC. 

Contrasted with:

     EXEC SQL SELECT DNAME, DEPTNO 
         FROM DEPT 
         WHERE EXISTS 
         (SELECT DEPTNO FROM EMP WHERE DEPT.DEPTNO = EMP.DEPTNO)
     END-EXEC. 

The first statement is slower because it does a time-consuming full scan of the EMP table for every department number in the DEPT table. Even if the DEPTNO column in EMP is indexed, the index is not used because the subquery lacks a WHERE clause naming DEPTNO.

Another cause of poor performance is unnecessary parsing and binding. Recall that before executing a SQL statement, Oracle must parse and bind it. Parsing means examining the SQL statement to make sure it follows syntax rules and refers to valid database objects. Binding means associating host variables in the SQL statement with their addresses so that Oracle can read or write their values.

Many applications manage cursors poorly. This results in unnecessary parsing and binding, which adds noticeably to processing overhead.

Improving Performance

If you are unhappy with the performance of your precompiled programs, there are several ways you can reduce overhead.

You can greatly reduce Oracle communication overhead, especially in networked environments, by

You can reduce processing overhead—sometimes dramatically—by

The following sections look at each of these ways to cut overhead.

Using Host Tables

Host tables can boost performance because they let you manipulate an entire collection of data with a single SQL statement. For example, suppose you want to insert salaries for 300 employees into the EMP table. Without tables your program must do 300 individual inserts—one for each employee. With arrays, only one INSERT is necessary. Consider the following statement:

     EXEC SQL INSERT INTO EMP (SAL) VALUES (:SALARY) END-EXEC.

If SALARY is a simple host variable, Oracle executes the INSERT statement once, inserting a single row into the EMP table. In that row, the SAL column has the value of SALARY. To insert 300 rows this way, you must execute the INSERT statement 300 times.

However, if SALARY is a host table of size 300, Oracle inserts all 300 rows into the EMP table at once. In each row, the SAL column has the value of an element in the SALARY table.

For more information, see Chapter 7, "Host Tables"

Using PL/SQL and Java

As Figure C-1 shows, if your application is database-intensive, you can use control structures to group SQL statements in a PL/SQL block, then send the entire block to Oracle. This can drastically reduce communication between your application and the database.

Also, you can use PL/SQL and Java subprograms to reduce calls from your application to the database. For example, to execute ten individual SQL statements, ten calls are required, but to execute a subprogram containing ten SQL statements, only one call is required.

Unlike anonymous blocks, PL/SQL and Java subprograms can be compiled separately and stored in a database. When called, they are passed to the PL/SQL engine immediately. Moreover, only one copy of a subprogram need be loaded into memory for execution by multiple users.

Figure C-1 PL/SQL Boosts Performance

PL/SQL Boosts Performance

Optimizing SQL Statements

For every SQL statement, the optimizer generates an execution plan, which is a series of steps that Oracle takes to execute the statement. These steps are determined by rules given in the Oracle Database Advanced Application Developer's Guide. Following these rules will help you write optimal SQL statements.

Optimizer Hints

For every SQL statement, the optimizer generates an execution plan, which is a series of steps that Oracle takes to execute the statement. In some cases, you can suggest the way to optimize a SQL statement. These suggestions, called hints, let you influence decisions made by the optimizer.

Hints are not directives; they merely help the optimizer do its job. Some hints limit the scope of information used to optimize a SQL statement, while others suggest overall strategies. You can use hints to specify the:

  • Optimization approach for a SQL statement

  • Access path for each referenced table

  • Join order for a join

  • Method used to join tables

Giving Hints

You give hints to the optimizer by placing them in a C-style Comment immediately after the verb in a SELECT, UPDATE, or DELETE statement. You can choose rule-based or cost-based optimization. With cost-based optimization, hints help maximize throughput or response time. In the following example, the ALL_ROWS hint helps maximize query throughput:

     EXEC SQL SELECT /*+ ALL_ROWS (cost-based) */ EMPNO, ENAME, SAL
         INTO :EMP-NUMBER, :EMP-NAME, :SALARY  
         FROM EMP 
         WHERE DEPTNO = :DEPT-NUMBER
     END-EXEC. 

The plus sign (+), which must immediately follow the Comment opener, indicates that the Comment contains one or more hints. Notice that the Comment can contain remarks as well as hints.

For more information about optimizer hints, see the Oracle Database Advanced Application Developer's Guide

Trace Facility

You can use the SQL trace facility and the EXPLAIN PLAN statement to identify SQL statements that might be slowing down your application. The trace facility generates statistics for every SQL statement executed by Oracle. From these statistics, you can determine which statements take the most time to process. You can then concentrate your tuning efforts on those statements.

The EXPLAIN PLAN statement shows the execution plan for each SQL statement in your application. You can use the execution plan to identify inefficient SQL statements.

See Also: Oracle Database Advanced Application Developer's Guide for instructions on using trace tools and analyzing their output.

SQL Statement Caching

Performance improvement is achieved in precompiler applications using statement caching. Any program using dynamic SQL statements, where the cursors have to be used with reparsing of the statements will have performance gain with statement caching. With this new feature, the overall execution time will be decreased.

The stmt_cache option can be set to hold the anticipated number of distinct dynamic SQL statements in the application. The customer can set the stmt_cache size with the new precompiler command line option. An optimal value of stmt_cache can not be set, as it depends on the input program behavior.

The performance can be measured with the change in the execution time (with and without statement caching).

Using Indexes

Using rowids, an index associates each distinct value in a table column with the rows containing that value. An index is created with the CREATE INDEX statement. For details, see the Oracle Database SQL Language Reference.

You can use indexes to boost the performance of queries that return less than 15% of the rows in a table. A query that returns 15% or more of the rows in a table is executed faster by a full scan, that is, by reading all rows sequentially. Any query that names an indexed column in its WHERE clause can use the index. For guidelines that help you choose which columns to index, see the Oracle Database Advanced Application Developer's Guide.

Taking Advantage of Row-Level Locking

By default, Oracle locks data at the row level rather than the table level. Row-level locking allows multiple users to access different rows in the same table concurrently. The resulting performance gain is significant.

You can specify table-level locking, but it lessens the effectiveness of the transaction processing option. For more information about table locking, see "Using the LOCK TABLE Statement" on "Using the LOCK TABLE Statement".

Applications that do online transaction processing benefit most from row-level locking. If your application relies on table-level locking, modify it to take advantage of row-level locking. In general, avoid explicit table-level locking.

Eliminating Unnecessary Parsing

Eliminating unnecessary parsing requires correct handling of cursors and selective use of the following cursor management options:

These options affect implicit and explicit cursors, the cursor cache, and private SQL areas.

Note: You can use the ORACA to get cursor cache statistics. See "Using the Oracle Communications Area".

Handling Explicit Cursors

Recall that there are two types of cursors: implicit and explicit (see "Errors and Warnings"). Oracle implicitly declares a cursor for all data definition and data manipulation statements. However, for queries that return more than one row, you should explicitly declare a cursor and fetch in batches rather than select into a host table. You use the DECLARE CURSOR statement to declare an explicit cursor. How you handle the opening and closing of explicit cursors affects performance.

If you need to reevaluate the active set, simply reopen the cursor. The OPEN statement will use any new host-variable values. You can save processing time if you do not close the cursor first.

Only CLOSE a cursor when you want to free the resources (memory and locks) acquired by OPENing the cursor. For example, your program should close all cursors before exiting.

Note: To make performance tuning easier, the precompiler lets you reopen an already open cursor. However, this is an Oracle extension to the ANSI/ISO embedded SQL standard. So, when MODE=ANSI, you must close a cursor before reopening it.

Cursor Control

In general, there are three factors that affect the control of an explicitly declared cursor:

  • Using the DECLARE, OPEN, FETCH, and CLOSE statements.

  • Using the PREPARE, DECLARE, OPEN, FETCH, and CLOSE statements

  • COMMIT closes the cursor when MODE=ANSI

With the first way, beware of unnecessary parsing. The OPEN statement does the parsing, but only if the parsed statement is unavailable because the cursor was closed or never opened. Your program should declare the cursor, re-open it every time the value of a host variable changes, and close it only when the SQL statement is no longer needed.

With the second way, which is used in dynamic SQL Methods 3 and 4, the PREPARE statement does the parsing, and the parsed statement is available until a CLOSE statement is executed. Your program should prepare the SQL statement and declare the cursor, re-open the cursor every time the value of a host variable changes, re-prepare the SQL statement and re-open the cursor if the SQL statement changes, and close the cursor only when the SQL statement is no longer needed.

When possible, avoid placing OPEN and CLOSE statements in a loop; this is a potential cause of unnecessary re-parsing of the SQL statement. In the next example, both the OPEN and CLOSE statements are inside the outer loop. When MODE=ANSI, the CLOSE statement must be positioned as shown, because ANSI requires a cursor to be closed before being re-opened.

     EXEC SQL DECLARE emp_cursor CURSOR FOR 
         SELECT ENAME, SAL FROM EMP
         WHERE SAL >  :SALARY
         AND SAL <= :SALARY + 1000
     END-EXEC. 
     MOVE 0 TO SALARY. 
 TOP. 
     EXEC SQL OPEN emp_cursor END-EXEC.
 LOOP.
     EXEC SQL FETCH emp_cursor INTO ....
     ... 
         IF SQLCODE = 0
              GO TO LOOP
          ELSE
              ADD 1000 TO SALARY
          END-IF.
     EXEC SQL CLOSE emp_cursor END-EXEC.
     IF SALARY < 5000
         GO TO TOP. 

With MODE=ORACLE, however, by placing the CLOSE statement outside the outer loop, you can avoid possible re-parsing at each iteration of the OPEN statement.

 TOP. 
     EXEC SQL OPEN emp_cursor END-EXEC.
 LOOP.
     EXEC SQL FETCH emp_cursor INTO ....
     ... 
         IF SQLCODE = 0
              GO TO LOOP
          ELSE
              ADD 1000 TO SALARY
          END-IF. 
     IF SALARY < 5000
         GO TO TOP. 
     EXEC SQL CLOSE emp_cursor END-EXEC.

Using the Cursor Management Options

A SQL statement need be parsed only once unless you change its makeup. For example, you change the makeup of a query by adding a column to its select list or WHERE clause. The HOLD_CURSOR, RELEASE_CURSOR, and MAXOPENCURSORS options give you some control over how Oracle manages the parsing and re-parsing of SQL statements. Declaring an explicit cursor gives you maximum control over parsing.

Private SQL Areas and Cursor Cache

When any statement is executed, its associated cursor is linked to an entry in the cursor cache. The cursor cache is a continuously updated area of memory used for cursor management. The cursor cache entry is in turn linked to a private SQL area.

The private SQL area, a work area created dynamically at run time by Oracle, contains the parsed SQL statement, the addresses of host variables, and other information needed to process the statement. Dynamic Method 3 lets you name a SQL statement, access the information in its private SQL area, and, to some extent, control its processing.

Figure C-2 represents the cursor cache after your program has done an insert and a delete.

Figure C-2 Cursors Linked through the Cursor Cache

Cursor Cache

Resource Use

The maximum number of open cursors for each user session is set by the initialization parameter OPEN_CURSORS.

MAXOPENCURSORS specifies the initial size of the cursor cache. If a new cursor is needed and there are no free cache entries, Oracle tries to reuse an entry. Its success depends on the values of HOLD_CURSOR and RELEASE_CURSOR and, for explicit cursors, on the status of the cursor itself.

If the value of MAXOPENCURSORS is less than the number of statements that need to be cached during the execution of the program, Oracle will search for cursor cache entries to reuse once MAXOPENCURSORS cache entries have been exhausted. For example, suppose the cache entry E(1) for an INSERT statement is marked as reusable, and the number of cache entries already equals MAXOPENCURSORS. If the program executes a new statement, cache entry E(1) and its private SQL area might be reassigned to the new statement. To reexecute the INSERT statement, Oracle would have to re-parse it and reassign another cache entry.

Oracle allocates an additional cache entry if it cannot find one to reuse. For example, if MAXOPENCURSORS=8 and all eight entries are active, a ninth is created. If necessary, Oracle keeps allocating additional cache entries until it runs out of memory or reaches the limit set by OPEN_CURSORS. This dynamic allocation adds to processing overhead.

Thus, specifying a low value for MAXOPENCURSORS with HOLD_CURSOR=NO (the default) saves memory but causes potentially expensive dynamic allocations and de-allocations of new cache entries. Specifying a high value for MAXOPENCURSORS assures speedy execution but uses more memory.

Infrequent Execution

Sometimes, the link between an infrequently executed SQL statement and its private SQL area should be temporary.

When HOLD_CURSOR=NO (the default), after Oracle executes the SQL statement and the cursor is closed, the precompiler marks the link between the cursor and cursor cache as reusable. The link is reused as soon as the cursor cache entry to which it points is needed for another SQL statement. This frees memory allocated to the private SQL area and releases parse locks. However, because a prepared cursor must remain active, its link is maintained even when HOLD_CURSOR=NO.

When RELEASE_CURSOR=YES, after Oracle executes the SQL statement and the cursor is closed, the private SQL area is automatically freed and the parsed statement lost. This might be necessary if, for example, you wish to conserve memory.

When RELEASE_CURSOR=YES, the link between the private SQL area and the cache entry is immediately removed and the private SQL area freed. Even if you tried to specify HOLD_CURSOR=YES, Oracle must still reallocate memory for a private SQL area and re-parse the SQL statement before executing it. Therefore, specifying RELEASE_CURSOR=YES overrides HOLD_CURSOR=YES.

Frequent Execution

The links between a frequently executed SQL statement and its private SQL area should be maintained, because the private SQL area contains all the information needed to execute the statement. Maintaining access to this information makes subsequent execution of the statement much faster.

When HOLD_CURSOR=YES, the link between the cursor and cursor cache is maintained after Oracle executes the SQL statement. Thus, the parsed statement and allocated memory remain available. This is useful for SQL statements that you want to keep active because it avoids unnecessary re-parsing.

Effect on the Shared SQL Area

Oracle caches the parsed representations of SQL statements and PL/SQL in its Shared SQL Cache. These representations are maintained until aged out by the need for the space to be used for other statements. For more information, see the Oracle Database Concepts manual. The behavior of the Oracle server in this respect is unaffected by the Precompiler's cursor management settings and so can have the following effects:

  • When RELEASE_CURSOR=YES and a statement is re executed, a request will be sent to the server to parse the statement but a full parse may not be necessary since the statement may still be cached.

  • When using HOLD_CURSOR=YES no locks are held on any objects referred to in the statement and so a redefinition of one of the objects in the statement will force the cached statement to become invalid and for the server to automatically reparse the statement. This may cause unexpected results.

  • Nonetheless, when RELEASE_CURSOR=YES, the re-parse might not require extra processing because Oracle caches the parsed representations of SQL statements and PL/SQL blocks in its Shared SQL Cache. Even if its cursor is closed, the parsed representation remains available until it is aged out of the cache.

Embedded PL/SQL Considerations

For the purposes of cursor management, an embedded PL/SQL block is treated just like a SQL statement. When an embedded PL/SQL block is executed, a parent cursor is associated with the entire block and a link is created between the cache entry and the private SQL area in the PGA for the embedded PL/SQL block. Be aware that each SQL statement inside the embedded block also requires a private SQL area in the PGA. These SQL statements use child cursors that PL/SQL manages itself. The disposition of the child cursors is determined through its associated parent cursor. That is, the private SQL areas used by the child cursors are freed after the private SQL area for its parent cursor is freed.

Note:

Using the defaults, HOLD_CURSOR=YES and RELEASE_CURSOR=NO, after executing a SQL statement with an earlier Oracle version, its parsed representation remains available. With Oracle, under similar conditions, the parsed representation remains available only until it is aged out of the Shared SQL Cache. Normally, this is not a problem, but you might get unexpected results if the definition of a referenced object changes before the SQL statement is re-parsed.

Parameter Interactions

Table C-1 shows how HOLD_CURSOR and RELEASE_CURSOR interact. Notice that HOLD_CURSOR=NO overrides RELEASE_CURSOR=NO and that RELEASE_CURSOR=YES overrides HOLD_CURSOR=YES.

Table C-1 HOLD_CURSOR and RELEASE _CURSOR Interactions

HOLD_CURSORRELEASE_CURSORLinks are...

NO

NO

marked as reusable

YES

NO

maintained

NO

YES

removed immediately

YES

YES

removed immediately


Avoiding Unnecessary Reparsing

When an embedded SQL statement is executed in a loop, it gets parsed only once. However, the execute phase of the SQL statement can result in errors, and statements are reparsed, with the following exceptions:

By correcting the errors, you can eliminate this unnecessary reparsing.

PKґau\uPKFJOEBPS/pcoaechk.htm>$ Syntactic and Semantic Checking

D Syntactic and Semantic Checking

By checking the syntax and semantics of embedded SQL statements and PL/SQL blocks, the Oracle Precompilers help you quickly find and fix coding mistakes. This appendix shows you how to use the SQLCHECK option to control the type and extent of checking.

Topics are:

Syntactic and Semantic Checking Basics

Rules of syntax specify how language elements are sequenced to form valid statements. Thus, syntactic checking verifies that keywords, object names, operators, delimiters, and so on are placed correctly in your SQL statement. It also applies to procedures and functions called from PL/SQL blocks. For example, the following embedded SQL statements contain syntax errors:

* --  misspelled keyword WHERE
     EXEC SQL DELETE FROM EMP WERE DEPTNO = 20 END-EXEC.
* --  missing parentheses around column names COMM and SAL
     EXEC SQL
         INSERT INTO EMP COMM, SAL VALUES (NULL, 1500)
     END-EXEC.

Rules of semantics specify how valid external references are made. Thus, semantic checking verifies that references to database objects and host variables are valid and that host-variable datatypes are correct. For example, the following embedded SQL statements contain semantic errors:

* --  nonexistent table, EMPP
     EXEC SQL DELETE FROM EMPP WHERE DEPTNO = 20 END-EXEC.
* --  undeclared host variable, EMP-NAME
     EXEC SQL SELECT * FROM EMP WHERE ENAME = :EMP-NAME END-EXEC.

The rules of SQL syntax and semantics are defined in the Oracle Database SQL Language Reference.

Controlling the Type and Extent of Checking

You control the type and extent of checking by specifying the SQLCHECK option on the command line. With SQLCHECK, the type of checking can be syntactic, or both syntactic and semantic. The extent of checking can include data manipulation statements and PL/SQL blocks. However, SQLCHECK cannot check dynamic SQL statements because they are not defined fully until run time.

You can specify the following values for SQLCHECK:

The values SEMANTICS and FULL are equivalent, as are the values SYNTAX and LIMITED. The default value is SYNTAX.

Specifying SQLCHECK=SEMANTICS

When SQLCHECK=SEMANTICS, the precompiler checks the syntax and semantics of

However, only syntactic checking is done on data manipulation statements that use the AT db_name clause.

The precompiler gets the information for a semantic check from embedded DECLARE TABLE statements or, if you specify the option USERID, by connecting to the database and accessing the data dictionary.

If you connect to the database but some table information cannot be found in the data dictionary, you must use DECLARE TABLE statements to supply the missing information. A DECLARE TABLE definition overrides a data dictionary definition if they conflict.

When checking data manipulation statements, the precompiler uses the Oracle set of syntax rules found in the Oracle Database SQL Language Reference but uses a stricter set of semantic rules. As a result, existing applications written for earlier versions of Oracle might not precompile successfully when SQLCHECK=SEMANTICS.

Specify SQLCHECK=SEMANTICS when precompiling new programs. If you embed PL/SQL blocks in a host program, you must specify SQLCHECK=SEMANTICS.

Enabling a Semantic Check

When SQLCHECK=SEMANTICS, the precompiler can get information needed for a semantic check in either of the following ways:

  • Connect to Oracle and access the data dictionary

  • Use embedded DECLARE TABLE statements

Connecting to Oracle

To do a semantic check, the precompiler can connect to the database that maintains definitions of tables and views referenced in your host program. After connecting, the precompiler accesses the data dictionary for needed information. The data dictionary stores table and column names, table and column constraints, column lengths, column datatypes, and so on.

If some of the needed information cannot be found in the data dictionary (because your program refers to a table not yet created, for example), you must supply the missing information using the DECLARE TABLE statement.

To connect to the database, specify the option USERID on the command line, using the syntax

USERID=username/password

where username and password comprise a valid Oracle userid. If you omit the password, you are prompted for it. If, instead of a username and password, you specify

USERID=/

the precompiler tries to connect to the database automatically with the userid

<prefix><username>

where prefix is the value of the initialization parameter OS_AUTHENT_PREFIX (the default value is OPS$) and username is your operating system user or task name.

If you try connecting, but cannot (for example, if the database is unavailable), the precompiler stops processing and issues an error message. If you omit the option USERID, the precompiler must get needed information from embedded DECLARE TABLE statements.

Using DECLARE TABLE

The precompiler can do a semantic check without connecting to the database as long as your program does not call any stored procedures or functions from an anonymous PL/SQL block. To do the check, the precompiler must get information about tables and views from embedded DECLARE TABLE directives. Thus, every table referenced in a data manipulation statement or PL/SQL block must be defined in a DECLARE TABLE statement.

The syntax of the DECLARE TABLE statement is

     EXEC SQL DECLARE table_name TABLE
         (col_name col_datatype [DEFAULT expr] [NULL|NOT NULL], ...)
     END-EXEC.

where expr is any expression that can be used as a default column value in the CREATE TABLE statement. col_datatype is an Oracle column declaration. Only integers can be used, not expressions. See "DECLARE TABLE (Oracle Embedded SQL Directive)".

If you use DECLARE TABLE to define a database table that already exists, the precompiler uses your definition, ignoring the one in the data dictionary.

PK(h# C$>$PKFJOEBPS/pcoabops.htm^ Operating System Dependencies

A Operating System Dependencies

Some details of COBOL programming vary from one system to another. This appendix is a collection of all system-specific issues regarding Pro*COBOL. References are provided, where applicable, to other sources in your document set.

System-Specific References in this Manual

System-specific references are described in the following section, grouped by subject area.

COBOL Versions

The Pro*COBOL Precompiler supports the standard implementation of COBOL for your operating system (usually COBOL-85 or COBOL-74). Some platforms may support both COBOL implementations. Check your Oracle system-specific documentation.

Host Variables

How you declare and name host variables depends on which COBOL compiler you use. Check your COBOL user's guide for details about declaring and naming host variables.

Declaring

Declare host variables according to COBOL rules, specifying a COBOL datatype supported by Oracle. Table 4-6, "Host Variable Declarations" shows the COBOL datatypes and pseudotypes you can specify. However, your COBOL implementation might not include all of them.

Naming

Host variable names must consist only of letters, digits, and hyphens. They must begin with a letter. They can be any length, but only the first 30 characters are significant. Your compiler might allow a different maximum length.

Due to a Pro*COBOL limitation, when interacting with SQLLIB (C routines), some unpredictable results may occur unless boundaries for host variables are properly aligned. Refer to your COBOL documentation for specific information on defining host variable boundary alignment. Work-arounds could include:

  • Manual alignment using FILLER

  • FORCE the boundary by using 01 level entries

  • If the data source is third party code, then use temporary variables at 77 level entries or 01 level entries, and use those as host variables.

INCLUDE Statements

You can INCLUDE any file. When you precompile your Pro*COBOL program, each EXEC SQL INCLUDE statement is replaced by a copy of the file named in the statement.

If your system uses file extensions but you do not specify one, the Pro*COBOL Precompiler assumes the default extension for source files (usually COB). The default extension is system-dependent. Check your Oracle system-specific documentation.

If your system uses directories, you can set a directory path for included files by specifying the precompiler option INCLUDE=path. You must use INCLUDE to specify a directory path for nonstandard files unless they are stored in the current directory. The syntax for specifying a directory path is system-specific. Check your Oracle system-specific documentation.

MAXLITERAL Default

With the MAXLITERAL precompiler option you can specify the maximum length of string literals generated by the precompiler, so that compiler limits are not exceeded. The MAXLITERAL default value is 256, but you might have to specify a lower value.

For example, if your COBOL compiler cannot handle string literals longer than 132 characters, specify "MAXLITERAL=132." Check your COBOL compiler user's guide. For more information about the MAXLITERAL option, see Chapter 14, "Precompiler Options"

PIC N or Pic G Clause for Multi-byte Globalization Support Characters

Some COBOL compilers may not support the use of the PIC N or PIC G clause for declaring multibyte Globalization Support character variables. Check your COBOL user's guide before writing source code that uses these clauses to declare multibyte character variables.

RETURN-CODE Special Register May Be Unpredictable.

The contents of the RETURN-CODE special register (for those systems that support it) are unpredictable after any SQL statement or SQLLIB function.

Byte-Order of Binary Data

On some platforms, the COBOL compiler reverses the byte-ordering of binary data. See your platform-specific documentation for the COMP5 precompiler option.

PKKiXc^PKFJOEBPS/pco07tab.htm Host Tables

7 Host Tables

This chapter looks at using host tables to simplify coding and improve program performance. You learn how to manipulate Oracle data using host tables, how to operate on all the elements of a host table with a single SQL statement, how to limit the number of table elements processed, and how to use tables of group items.

The main sections are:

Host Tables

A host table (also known as an array) is a set of related data items, called elements, associated with a single variable. An indicator variable defined as a table is called an indicator table. An indicator table can be associated with any host table that is NULLABLE.

Advantages of Host Tables

Host tables can ease programming and can offer greatly improved performance. When writing an application, you are usually faced with the problem of storing and manipulating large amounts of data. Host tables simplify the task of accessing multiple return values.

Host tables let you manipulate multiple rows with a single SQL statement. Thus, communications overhead is reduced markedly, especially in a networked environment. For example, suppose you want to insert information about 300 employees into the EMP table. Without host tables your program must do 300 individual INSERTs—one for each employee. With host tables, only one INSERT need be done.

Tables in Data Manipulation Statements

Pro*COBOL allows the use of host tables in data manipulation statements. You can use host tables as input variables in the INSERT, UPDATE, and DELETE statements and as output variables in the INTO clause of SELECT and FETCH statements.

The syntax used for host tables and for simple host variables is nearly the same. One difference is the optional FOR clause, which lets you control table processing. Also, there are restrictions on mixing host tables and simple host variables in a SQL statement.

Declaring Host Tables

You declare and dimension host tables in the Data Division. In the following example, three host tables are declared, each dimensioned with 50 elements:

     .... 
 01  EMP-TABLES. 
     05  EMP-NUMBER  OCCURS 50 TIMES PIC S9(4) COMP. 
     05  EMP-NAME    OCCURS 50 TIMES PIC X(10. 
     05  SALARY      OCCURS 50 TIMES PIC S9(5)V99 COMP-3. 
     .... 

You can use the INDEXED BY phrase in the OCCURS clause to specify an index, as the next example shows:

     ... 
 01  EMP-TABLES. 
     05  EMP-NUMBER  PIC X(10) OCCURS 50 TIMES 
         INDEXED BY EMP-INDX. 
             ... 
     ... 

The INDEXED BY phrase implicitly declares the index item EMP-INDX.

Restrictions

Multi-dimensional host tables are not allowed. Thus, the two-dimensional host table declared in the following example is invalid:

     ... 
 01  NATION.
     05  STATE                OCCURS 50 TIMES. 
         10  STATE-NAME       PIC X(25).
         10  COUNTY           OCCURS 25 TIMES.
             15  COUNTY-NAME  PIX X(25).
     ... 

Variable-length host tables are not allowed either. For example, the following declaration of EMP-REC is invalid for a host variable:

     ... 
 01  EMP-FILE. 
     05  REC-COUNT  PIC S9(3) COMP. 
     05  EMP-REC    OCCURS 0 TO 250 TIMES 
         DEPENDING ON REC-COUNT. 
     ... 

The maximum number of host table elements in a SQL statement that is accessible in one fetch is 32K (or possibly greater, depending on your platform and the available memory). If you try to access a number that exceeds the maximum, you get a "parameter out of range" runtime error. If the statement is an anonymous PL/SQL block, the number of elements accessible is limited to 32512 divided by the size of the datatype.

Referencing Host Tables

If you use multiple host tables in a single SQL statement, their dimensions should be the same. This is not a requirement, however, because Pro*COBOL always uses the smallest dimension for the SQL operation. In the following example, only 25 rows are inserted

 WORKING-STORAGE SECTION. 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMP-TABLES. 
     05  EMP-NUMBER   PIC S9(4) COMP OCCURS 50 TIMES. 
     05  EMP-NAME     PIC X(10) OCCURS 50 TIMES. 
     05  DEPT-NUMBER  PIC S9(4) COMP OCCURS 25 TIMES. 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION. 
     ... 
*    Populate host tables here. 
     ... 
     EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO) 
         VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER) 
     END-EXEC. 

Host tables must not be subscripted in SQL statements. For example, the following INSERT statement is invalid:

 WORKING-STORAGE SECTION. 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMP-TABLES. 
     05  EMP-NUMBER   PIC S9(4) COMP OCCURS 50 TIMES. 
     05  EMP-NAME     PIC X(10) OCCURS 50 TIMES. 
     05  DEPT-NUMBER  PIC S9(4) COMP OCCURS 50 TIMES. 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION. 
     ... 
     PERFORM LOAD-EMP VARYING J FROM 1 BY 1 UNTIL J > 50. 
     ... 
 LOAD-EMP. 
     EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO) 
         VALUES (:EMP-NUMBER(J), :EMP-NAME(J), 
             :DEPT-NUMBER(J)) 
     END-EXEC. 

You need not process host tables in a PERFORM VARYING statement. Instead, use the un-subscripted table names in your SQL statement. Pro*COBOL treats a SQL statement containing host tables of dimension n like the same statement executed n times with n different scalar host variables, but more efficiently.

Using Indicator Tables

You can use indicator tables to assign NULLs to elements in input host tables and to detect NULLs or truncated values (of character columns only) in output host tables. The following example shows how to conduct an INSERT with indicator tables:

 WORKING-STORAGE SECTION. 
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
 01  EMP-TABLES. 
     05  EMP-NUMBER   PIC S9(4) COMP OCCURS 50 TIMES. 
     05  DEPT-NUMBER  PIC S9(4) COMP OCCURS 50 TIMES. 
     05  COMMISSION   PIC S9(5)V99 COMP-3 OCCURS 50 TIMES. 
     05  COMM-IND     PIC S9(4) COMP OCCURS 50 TIMES. 
     EXEC SQL END DECLARE SECTION END-EXEC. 
     ... 
 PROCEDURE DIVISION. 
     ... 
*    Populate the host and indicator tables. 
*    Set indicator table to all zeros.
     ... 
     EXEC SQL INSERT INTO EMP (EMPNO, DEPTNO, COMM) 
         VALUES (:EMP-NUMBER, :DEPT-NUMBER, 
             :COMMISSION:COMM-IND) 
     END-EXEC. 

The dimension of the indicator table must be greater than or equal to the dimension of the host table.

When using host table SELECT and FETCH, it is recommended that you use indicator variables. That way you can test for NULLs in the associated output host table.

If a NULL is selected or fetched into a host variable that has no associated indicator variable, your program stops processing, sets sqlca.sqlerrd(3) to the number of rows processed, and returns an error.

NULL is selected by default, but you can switch it off by using the UNSAFE_NULL = YES option.

When DBMS=V7 or V8, your program does not consider truncation to be an error.

Host Group Item Containing Tables

Note: If you have a host group item containing tables, then you must use a corresponding group item of tables for an indicator. For example, if your group item is the following:

 01  DEPARTURE.
     05 HOUR    PIC X(2) OCCURS 3 TIMES.
     05 MINUTE  PIC X(2) OCCURS 3 TIMES.

the following indicator variable cannot be used:

 01  DEPARTURE-IND PIC S9(4) COMP OCCURS 6 TIMES.

The indicator variable you use with the group item of tables must itself be a group item of tables such as the following:

  01  DEPARTURE-IND.
      05 HOUR-IND   PIC S9(4) COMP OCCURS 3 TIMES.
      05 MINUTE-IND PIC S9(4) COMP OCCURS 3 TIMES.

Oracle Restrictions

Mixing scalar host variables with host tables in the VALUES, SET, INTO, or WHERE clause is not allowed. If any of the host variables is a host table, all must be host tables.

You cannot use host tables with the CURRENT OF clause in an UPDATE or DELETE statement.

ANSI Restriction and Requirements

The array interface is an Oracle extension to the ANSI/ISO embedded SQL standard. However, when you precompile with MODE=ANSI, array SELECTs and FETCHes are still allowed. The use of arrays can be flagged using the FIPS flagger precompiler option, if desired.

Selecting into Tables

You can use host tables as output variables in the SELECT statement. If you know the maximum number of rows the select will return, simply define the host tables with that number of elements. In the following example, you select directly into three host tables. The table was defined with 50 rows, with the knowledge that the select will return no more than 50 rows.

     01  EMP-REC-TABLES.
         05  EMP-NUMBER   OCCURS 50 TIMES PIC S9(4) COMP.
         05  EMP-NAME     OCCURS 50 TIMES PIC X(10) VARYING.
         05  SALARY       OCCURS 50 TIMES PIC S9(6)V99
                          DISPLAY SIGN LEADING SEPARATE.
     ...
     EXEC SQL SELECT ENAME, EMPNO, SAL
         INTO :EMP-NAME, :EMP-NUMBER, :SALARY
         FROM EMP
         WHERE SAL > 1000
     END-EXEC.

In this example, the SELECT statement returns up to 50 rows. If there are fewer than 50 eligible rows or you want to retrieve only 50 rows, this method will suffice. However, if there are more than 50 eligible rows, you cannot retrieve all of them this way. If you reexecute the SELECT statement, it just returns the first 50 rows again, even if more are eligible. You must either define a larger table or declare a cursor for use with the FETCH statement.

If a SELECT INTO statement returns more rows than the size of the table you defined, Oracle issues an error message unless you specify SELECT_ERROR=NO. For more information about the option, see "SELECT_ERROR".

Batch Fetches

Use batch fetches when the size of data you are processing is large (greater than about 100 rows) as well as when you do not know how many rows will be returned.

If you do not know the maximum number of rows a select will return, you can declare and open a cursor, and then fetch from it in "batches." Batch fetches within a loop let you retrieve a large number of rows with ease. Each fetch returns the next batch of rows from the current active set. In the following example, you fetch in 20-row batches:

 ...
 01  EMP-REC-TABLES.
     05  EMP-NUMBER    OCCURS 20 TIMES PIC S9(4) COMP.
     05  EMP-NAME      OCCURS 20 TIMES PIC X(10) VARYING.
     05  SALARY        OCCURS 20 TIMES PIC S9(6)V99
                       DISPLAY SIGN LEADING SEPARATE.
     ...
     EXEC SQL DECLARE EMPCURSOR CURSOR FOR
     SELECT EMPNO, SAL FROM EMP
     END-EXEC.
     ...
     EXEC SQL OPEN EMPCURSOR END-EXEC.
     ...
     EXEC SQL WHENEVER NOT FOUND DO PERFORM END-IT.
 LOOP.
     EXEC SQL FETCH EMPCURSOR INTO :EMP-NUMBER, :SALARY END-EXEC.
* --  process batch of rows
     ...
     GO TO LOOP.
 END-IT.
...

Do not forget to check how many rows were actually returned in the last fetch and to process them. See "Sample Program 3: Fetching in Batches" for a complete example.

Using SQLERRD(3)

For INSERT, UPDATE, and DELETE statements, SQLERRD(3) records the number of rows processed.

SQLERRD(3) is also useful when an error occurs during a table operation. Processing stops at the row that caused the error, so SQLERRD(3) gives the number of rows processed successfully.

Number of Rows Fetched

Each fetch returns, at most, the number of entries in the table. Fewer rows are returned in the following cases:

  • The end of the active set is reached. The "no data found" warning code is returned to SQLCODE in the SQLCA. For example, this happens if you fetch into a table of number of entries 100, but only 20 rows are returned.

  • Fewer than a full batch of rows remain to be fetched. For example, this happens if you fetch 70 rows into a table of number of entries 20 because after the third fetch, only 10 rows remain to be fetched.

  • An error is detected while processing a row. The fetch fails and the applicable error code is returned to SQLCODE.

The cumulative number of rows returned can be found in the third element of SQLERRD in the SQLCA, called SQLERRD(3) in this guide. This applies to each open cursor. In the following example, notice how the status of each cursor is maintained separately:

     EXEC SQL OPEN CURSOR1 END-EXEC.
     EXEC SQL OPEN CURSOR2 END-EXEC.
     EXEC SQL FETCH CURSOR1 INTO :TABLE-OF-20 END-EXEC.
* --  now running total in SQLERRD(3) is 20
     EXEC SQL FETCH CURSOR2 INTO :TABLE-OF-30 END-EXEC.
* --  now running total in SQLERRD(3) is 30, not 50
     EXEC SQL FETCH CURSOR1 INTO :TABLE-OF-20 END-EXEC.
* --  now running total in SQLERRD(3) is 40 (20 + 20)
     EXEC SQL FETCH CURSOR2 INTO :TABLE-OF-30 END-EXEC.
* --  now running total in SQLERRD(3) is 60 (30 + 30)

Restrictions on Using Host Tables

Using host tables in the WHERE clause of a SELECT statement is allowed only in a sub-query. (For an example, see "The WHERE Clause".) Also, since Pro*COBOL always takes the smallest dimension of table, do not mix simple host variables with host tables in the INTO clause of a SELECT or FETCH statement because only one row will be retrieved. If any of the host variables is a table, then all must be tables.

Table 7-1 shows which uses of host tables are valid in a SELECT INTO statement.

Table 7-1 Host Tables Valid in SELECT INTO

INTO ClauseWHERE ClauseValid?

table

table

no

scalar

scalar

yes

table

scalar

yes

scalar

table

no


Fetching NULLs

When UNSAFE_NULL=YES, if you select or fetch a NULL into a host table that lacks an indicator table, no error is generated. So, when doing table selects and fetches, Oracle recommends that you use indicator tables. This is because this makes it NULLs easier to find in the associated output host table. (To learn how to find NULLs and truncated values, see "Using Indicator Variables".)

When UNSAFE_NULL=NO, if you select or fetch a NULL into a host table that lacks an indicator table, Oracle stops processing, sets SQLERRD(3) to the number of rows processed, and issues an error message:

Fetching Truncated Values

If you select or fetch a truncated column value into a host table that lacks an indicator table, Oracle sets SQLWARN(2).

You can check SQLERRD(3) for the number of rows processed before the truncation occurred. The rows-processed count includes the row that caused the truncation error.

When doing table selects and fetches, you can use indicator tables. That way, if Oracle assigns one or more truncated column values to an output host table, you can find the original lengths of the column values in the associated indicator table.

Sample Program 3: Fetching in Batches

The following host table sample program can be found in the demo directory.

      *****************************************************************
      * Sample Program 3:  Host Tables                                *
      *                                                               *
      * This program logs on to ORACLE, declares and opens a cursor,  *
      * fetches in batches using host tables, and prints the results. *
      *****************************************************************

       IDENTIFICATION DIVISION.
       PROGRAM-ID. HOST-TABLES.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME          PIC X(15) VARYING.
       01  PASSWD            PIC X(15) VARYING.
       01  EMP-REC-TABLES.
           05  EMP-NUMBER    OCCURS 5 TIMES PIC S9(4) COMP.
           05  EMP-NAME      OCCURS 5 TIMES PIC X(10) VARYING.
           05  SALARY        OCCURS 5 TIMES PIC S9(6)V99
                             DISPLAY SIGN LEADING SEPARATE.
           EXEC SQL VAR SALARY IS DISPLAY(8,2) END-EXEC.
           EXEC SQL END DECLARE SECTION END-EXEC.
           EXEC SQL INCLUDE SQLCA END-EXEC.
       01  NUM-RET           PIC S9(9) COMP VALUE ZERO.
       01  PRINT-NUM         PIC S9(9) COMP VALUE ZERO.
       01  COUNTER           PIC S9(9) COMP.
       01  DISPLAY-VARIABLES.
           05  D-EMP-NAME    PIC X(10).
           05  D-EMP-NUMBER  PIC 9(4).
           05  D-SALARY      PIC Z(4)9.99.

       PROCEDURE DIVISION.

       BEGIN-PGM.
           EXEC SQL 
               WHENEVER SQLERROR DO PERFORM SQL-ERROR
           END-EXEC.
           PERFORM LOGON.
           EXEC SQL 
               DECLARE C1 CURSOR FOR
               SELECT EMPNO, SAL, ENAME 
               FROM EMP
           END-EXEC.
           EXEC SQL
               OPEN C1
           END-EXEC.

       FETCH-LOOP.
           EXEC SQL 
               WHENEVER NOT FOUND DO PERFORM SIGN-OFF
           END-EXEC.
           EXEC SQL 
               FETCH C1 
               INTO :EMP-NUMBER, :SALARY, :EMP-NAME
           END-EXEC.
           SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
           PERFORM PRINT-IT.
           MOVE SQLERRD(3) TO NUM-RET.
           GO TO FETCH-LOOP.

       LOGON.
           MOVE "SCOTT" TO USERNAME-ARR.
           MOVE 5 TO USERNAME-LEN.
           MOVE "TIGER" TO PASSWD-ARR.
           MOVE 5 TO PASSWD-LEN.
           EXEC SQL
              CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
           DISPLAY " ".
           DISPLAY "CONNECTED TO ORACLE AS USER:  ", USERNAME-ARR.

       PRINT-IT.
           DISPLAY " ".
           DISPLAY "EMPLOYEE NUMBER  SALARY   EMPLOYEE NAME".
           DISPLAY "---------------  -------  -------------".
           PERFORM PRINT-ROWS
               VARYING COUNTER FROM 1 BY 1
               UNTIL COUNTER > PRINT-NUM.

       PRINT-ROWS.      
           MOVE EMP-NUMBER(COUNTER) TO D-EMP-NUMBER.
           MOVE SALARY(COUNTER) TO D-SALARY.
           DISPLAY "           ", D-EMP-NUMBER, " ", D-SALARY, "  ",
               EMP-NAME-ARR IN EMP-NAME(COUNTER).
           MOVE SPACES TO EMP-NAME-ARR IN EMP-NAME(COUNTER).

       SIGN-OFF.
           SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
           IF (PRINT-NUM > 0) PERFORM PRINT-IT.
           EXEC SQL 
               CLOSE C1 
           END-EXEC. 
           EXEC SQL 
               COMMIT WORK RELEASE 
           END-EXEC.
           DISPLAY " ".
           DISPLAY "HAVE A GOOD DAY.".
           DISPLAY " ".
           STOP RUN.

       SQL-ERROR.
           EXEC SQL 
               WHENEVER SQLERROR CONTINUE 
           END-EXEC.
           DISPLAY " ".
           DISPLAY "ORACLE ERROR DETECTED:".
           DISPLAY " ".
           DISPLAY SQLERRMC.
           EXEC SQL 
               ROLLBACK WORK RELEASE 
           END-EXEC.
           STOP RUN.

Inserting with Tables

You can use host tables as input variables in an INSERT statement. Just make sure your program populates the tables with data before executing the INSERT statement. If some elements in the tables are irrelevant, you can use the FOR clause to control the number of rows inserted. See "The FOR Clause".

An example of inserting with host tables follows:

 01  EMP-REC-TABLES.
     05  EMP-NUMBER    OCCURS 50 TIMES PIC S9(4) COMP.
     05  EMP-NAME      OCCURS 50 TIMES PIC X(10) VARYING.
     05  SALARY        OCCURS 50 TIMES PIC S9(6)V99
                       DISPLAY SIGN LEADING SEPARATE.
* -- populate the host tables
     EXEC SQL INSERT INTO EMP (ENAME, EMPNO, SAL)
         VALUES (:EMP-NAME, :EMP-NUMBER, :SALARY)
     END-EXEC.

The number of rows inserted will be available in SQLERRD(3).

Host tables must not be subscripted in SQL statements. For example the following INSERT statement is invalid:

     PERFORM VARYING I FROM 1 BY 1 UNTIL I = TABLE-DIMENSION.
        EXEC SQL INSERT INTO EMP (ENAME, EMPNO, SAL)
            VALUES (:EMP-NAME(I), :EMP-NUMBER(I), :SALARY(I))
        END_EXEC
     END-PERFORM.

Restrictions on Host Tables

Mixing simple host variables with host tables in the VALUES clause of an INSERT, UPDATE, or DELETE statement causes only the first element of any host table to be processed because simple host variables are treated as host tables of dimension one and Pro*COBOL always uses the smallest declared dimension. You receive a warning when this occurs.

Updating with Tables

You can also use host tables as input variables in an UPDATE statement, as the following example shows:

 01  EMP-REC-TABLES.
     05  EMP-NUMBER    OCCURS 50 TIMES PIC S9(4) COMP.
     05  SALARY        OCCURS 50 TIMES PIC S9(6)V99 
                           DISPLAY SIGN LEADING SEPARATE.
 ...
* --  populate the host tables
     EXEC SQL
         UPDATE EMP SET SAL = :SALARY WHERE EMPNO = :EMP-NUMBER
     END-EXEC.

The number of rows updated by issuing this statement is available in SQLERRD(3). This is not necessarily the number of rows in the host table. The number does not include rows processed by an update cascade (which causes subsequent updates.)

If some elements in the tables are irrelevant, you can use the FOR clause to limit the number of rows updated.

The last example showed a typical update using a unique key (EMP-NUMBER). Each table element qualified just one row for updating. In the following example, each table element qualifies multiple rows:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
     ...
            05  JOB-TITLE      OCCURS 10 TIMES PIC X(10) VARYING.
            05  COMMISSION     OCCURS 50 TIMES PIC S9(6)V99
                              DISPLAY SIGN LEADING SEPARATE.
     EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host tables
     EXEC SQL
         UPDATE EMP SET COMM = :COMMISSION WHERE JOB = :JOB-TITLE
     END-EXEC.

Restrictions in UPDATE

You cannot use host tables with the CURRENT OF clause in an UPDATE statement. For an alternative, see "Mimicking the CURRENT OF Clause".

Table 7-2 shows which uses of host tables are valid in an UPDATE statement:

Table 7-2 Host Tables Valid in UPDATE

SET ClauseWHERE ClauseValid?

table

table

yes

scalar

scalar

yes

table

scalar

no

scalar

table

no


Deleting with Tables

You can also use host tables as input variables in a DELETE statement. Doing so is like executing the DELETE statement repeatedly using successive elements of the host table in the WHERE clause. Thus, each execution might delete zero, one, or more rows from the table. An example of deleting with host tables follows:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
     ... 
         05  EMP-NUMBER    OCCURS 50 TIMES PIC S9(4) COMP.
     EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host table
     EXEC SQL
         DELETE FROM EMP WHERE EMPNO = :EMP-NUMBER
     END-EXEC.

The cumulative number of rows deleted can be found in SQLERRD(3). That number does not include rows processed by a delete cascade.

The last example showed a typical delete using a unique key (EMP-NUMBER). Each table element qualified just one row for deletion. In the following example, each table element qualifies multiple rows:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
     ...
            05  JOB-TITLE    OCCURS 10 TIMES PIC X(10) VARYING.
     EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host table
     EXEC SQL
        DELETE FROM EMP WHERE JOB = :JOB-TITLE
     END-EXEC.

Restrictions in DELETE

You cannot use host tables with the CURRENT OF clause in a DELETE statement. For an alternative, see "Mimicking the CURRENT OF Clause".

Using Indicator Tables

You use indicator tables to assign NULLs to input host tables and to detect NULL or truncated values in output host tables. The following example shows how to insert with indicator tables:

 01  EMP-REC-VARS.
     05  EMP-NUMBER  OCCURS 50 TIMES PIC S9(4) COMP.
     05  DEPT-NUMBER OCCURS 50 TIMES PIC S9(4) COMP.
     05  COMMISSION  OCCURS 50 TIMES  PIC S9(6)V99
                            DISPLAY SIGN LEADING SEPARATE.
* -- indicator table:
     05  COMM-IND    OCCURS 50 TIMES  PIC S9(4) COMP.
* --  populate the host tables
* --  populate the indicator table; to insert a NULL into 
* --  the COMM column, assign -1 to the appropriate element in
* --  the indicator table
     EXEC SQL
         INSERT INTO EMP (EMPNO, DEPTNO, COMM)
         VALUES (:EMP_NUMBER, :DEPT-NUMBER, :COMMISSION:COMM-IND)
     END-EXEC.

The number of entries of the indicator table cannot be smaller than the number of entries of the host table.

The FOR Clause

You can use the optional FOR clause to set the number of table elements processed by any of the following SQL statements:

The FOR clause is especially useful in UPDATE, INSERT, and DELETE statements. With these statements you might not want to use the entire table. The FOR clause lets you limit the elements used to just the number you need, as the following example shows:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
 01  EMP-REC-VARS.
     05  EMP-NAME  OCCURS 1000 TIMES  PIC X(20) VARYING.
     05  SALARY    OCCURS 100  TIMES  PIC S9(6)V99
                   DISPLAY SIGN LEADING SEPARATE.
 01 ROWS-TO-INSERT PIC S9(4) COMP.
     EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host tables
     MOVE 25 TO ROWS-TO-INSERT.
* -- set FOR-clause variable
* -- will process only 25 rows
     EXEC SQL FOR :ROWS-TO-INSERT  
         INSERT INTO EMP (ENAME, SAL)
         VALUES (:EMP-NAME, :SALARY)
     END-EXEC.

The FOR clause must use an integer host variable to count table elements. For example, the following statement is illegal:

* -- illegal
     EXEC SQL FOR 25           
     INSERT INTO EMP (ENAME, EMPNO, SAL)
         VALUES (:EMP-NAME, :EMP-NUMBER, :SALARY)
     END-EXEC.

The FOR clause variable specifies the number of table elements to be processed. Make sure the number does not exceed the smallest table dimension. Internally, the value is treated as an unsigned quantity. An attempt to pass a negative value through the use of a signed host variable will result in unpredictable behavior.

Restrictions

Two restrictions keep FOR clause semantics clear: you cannot use the FOR clause in a SELECT statement or with the CURRENT OF clause.

In a SELECT Statement

If you use the FOR clause in a SELECT statement, you receive an error message.

The FOR clause is not allowed in SELECT statements because its meaning is unclear. Does it mean "execute this SELECT statement n times"? Or, does it mean "execute this SELECT statement once, but return n rows"? The problem in the former case is that each execution might return multiple rows. In the latter case, it is better to declare a cursor and use the FOR clause in a FETCH statement, as follows:

     EXEC SQL FOR :LIMIT FETCH EMPCURSOR INTO ...

With the CURRENT OF Clause

You can use the CURRENT OF clause in an UPDATE or DELETE statement to refer to the latest row returned by a FETCH statement, as the following example shows:

     EXEC SQL DECLARE EMPCURSOR CURSOR FOR 
         SELECT ENAME, SAL FROM EMP WHERE EMPNO = :EMP-NUMBER
     END-EXEC.
     ... 
     EXEC SQL OPEN EMPCURSOR END-EXEC.
     ...
     EXEC SQL FETCH emp_cursor INTO :EM-NAME, :SALARY END-EXEC.
     ...
     EXEC SQL UPDATE EMP SET SAL = :NEW-SALARY
         WHERE CURRENT OF EMPCURSOR
     END-EXEC.

However, you cannot use the FOR clause with the CURRENT OF clause. The following statements are invalid because the only logical value of LIMIT is 1 (you can only update or delete the current row once):

     EXEC SQL FOR :LIMIT UPDA-CURSOR END-EXEC.
     ...
     EXEC SQL FOR :LIMIT DELETE FROM EMP 
         WHERE CURRENT OF emp_cursor
     END-EXEC.

The WHERE Clause

Pro*COBOL treats a SQL statement containing host tables of number of entries n like the same SQL statement executed n times with n different scalar variables (the individual table elements). The precompiler issues an error message only when such treatment is ambiguous:

For example, assuming the declarations:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
     ...
     05  MGRP-NUMBER  OCCURS 50 TIMES  PIC S9(4) COMP.
     05  JOB-TITLE    OCCURS 50 TIMES  PIC X(20) VARYING.
 01  I PIC S9(4) COMP.
     EXEC SQL END DECLARE SECTION END-EXEC.

it would be ambiguous if the statement:

     EXEC SQL SELECT MGR INTO :MGR-NUMBER FROM EMP
         WHERE JOB = :JOB-TITLE
     END-EXEC.

were treated like the following statement

     PERFORM VARYING I FROM 1 BY 1 UNTIL I = 50
     SELECT MGR INTO :MGR-NUMBER(I) FROM EMP
         WHERE JOB = :JOB_TITLE(I)
     END-EXEC
     END-PERFORM.

because multiple rows might meet the WHERE-clause search condition, but only one output variable is available to receive data. Therefore, an error message is issued.

On the other hand, it would not be ambiguous if the statement

      EXEC SQL
         UPDATE EMP SET MGR = :MGR_NUMBER
         WHERE EMPNO IN (SELECT EMPNO FROM EMP WHERE
         JOB = :JOB-TITLE)
     END-EXEC.

were treated like the following statement

     PERFORM VARYING I FROM 1 BY 1 UNTIL I = 50
         UPDATE EMP SET MGR = :MGR_NUMBER(I)
             WHERE EMPNO IN
             (SELECT EMPNO FROM EMP WHERE JOB = :JOB-TITLE(I))
         END-EXEC
     END-PERFORM.

because there is a MGR-NUMBER in the SET clause for each row matching JOB-TITLE in the WHERE clause, even if each JOB-TITLE matches multiple rows. All rows matching each JOB-TITLE can be SET to the same MGR-NUMBER, so no error message is issued.

Mimicking the CURRENT OF Clause

The CURRENT OF clause enables you to do UPDATEs or DELETEs of the most recent row in the cursor. Use of the CURRENT OF clause causes the FOR UPDATE clause to be added to the cursor. Adding this clause has the effect of locking all rows identified by the cursor in exclusive mode. Note that you cannot use CURRENT OF with host tables. Instead, append FOR UPDATE to the definition of the cursor and explicitly select the ROWID column, then use that value to identify the current row during the update or delete. An example follows:

         05  EMP-NAME    OCCURS 25 TIMES PIC X(20) VARYING.
         05  JOB-TITLE   OCCURS 25 TIMES PIC X(15) VARYING.
         05  OLD-TITLE   OCCURS 25 TIMES PIC X(15) VARYING.
         05  ROW-ID      OCCURS 25 TIMES PIC X(18) VARYING.
     ...
     EXEC SQL DECLARE EMPCURSOR CURSOR FOR
         SELECT ENAME, JOB, ROWID FROM EMP
         FOR UPDATE
     END-EXEC.
     ...
     EXEC SQL OPEN EMPCURSOR END-EXEC.
     ...
     EXEC SQL WHENEVER NOT FOUND GOTO ...
     ...
     PERFORM
         EXEC SQL
             FETCH EMPCURSOR
             INTO :EMP-NAME, :JOB-TITLE, :ROW-ID
         END-EXEC
         ...
         EXEC SQL
             DELETE FROM EMP
             WHERE JOB = :OLD-TITLE AND ROWID = :ROW-ID
         END-EXEC
         EXEC SQL COMMIT WORK END-EXEC
      END-PERFORM.

Tables of Group Items as Host Variables

Pro*COBOL allows the use of tables of group items (also called records) in embedded SQL statements. The tables of group items can be referenced in the INTO clause of a SELECT or a FETCH statement, and in the VALUES list of an INSERT statement.

For example, given the following declaration:

 01    TABLES.
       05   EMP-TABLE           OCCURS 20 TIMES.
            10    EMP-NUMBER    PIC S9(4) COMP.
            10    EMP-NAME      PIC X(10).
            10    DEPT-NUMBER   PIC S9(4) COMP.

the following statement is valid:

       EXEC SQL INSERT INTO EMP(EMPNO, ENAME, DEPTNO)
            VALUES(:EMP-TABLE)
       END-EXEC.

Assuming that the group item has been filled with data already, the statement bulk inserts 20 rows consisting of the employee number, employee name, and department number into the EMP table.

Make sure that the order of the group items corresponds to the order in the SQL statement.

To use an indicator variable, set up a second table of a group item that contains an indicator variable for each variable in the group item:

 01     TABLES-IND.
        05   EMP-TABLE-IND  OCCURS 20 TIMES.
             10   EMP-NUMBER-IND       PIC S9(4) COMP.
             10   EMP-NAME-IND         PIC S9(4) COMP.
             10   DEPT-NUMBER_IND      PIC S9(4) COMP.

The host indicator table of a group item can be used as follows:

        EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
            VALUES (:EMP-TABLE:EMP-TABLE-IND)
        END-EXEC.

If the exact characteristics of the data are known, it is convenient to specify an elementary item indicator for a group item:

        05    EMP-TABLE-IND     PIC S9(4) COMP
                                OCCURS 20 TIMES.

Host tables of group items cannot have group items that are tables. For example:

 01   TABLES.
      05   EMP-TABLE               OCCURS 20 TIMES.
           10  EMP-NUMBER          PIC S9(4) COMP OCCURS 10 TIMES.
           10  EMP-NAME            PIC X(10).
           10  DEPT-NUMBER         PIC S9(4) COMP.

EMP-TABLE cannot be used as a host variable because EMP-NUMBER is a table.

Host tables of nested group items are not allowed. For example:

 01   TABLES.
      05   TEAM-TABLE                   OCCURS 20 TIMES
           10   EMP-TABLE
                15   EMP-NUMBER         PIC S9(4) COMP.
                15   EMP-NAME           PIC X(10).
           10   DEPT-TABLE.
                15   DEPT-NUMBER        PIC S9(4) COMP.
                15   DEPT-NAME          PIC X(10).

TEAM-TABLE cannot be used as a host variable because its members (EMP-TABLE and DEPT-TABLE) are group items themselves.

Finally, the restrictions that apply to host tables in Pro*COBOL also apply to tables of group items:

Sample Program 14: Tables of Group Items

This program logs on, declares and opens a cursor, fetches in batches using a table of group items. Read the initial comments for details.

      *****************************************************************
      * Sample Program 14:  Tables of group items                     *
      *                                                               *
      * This program logs on to ORACLE, declares and opens a cursor,  *
      * fetches in batches using a table of group items , and prints  *
      * the results.  This sample is identical to sample3 except that *
      * instead of using three separate host tables of five elements  *
      * each, it uses a five-element table of three group items.      *
      * The output should be identical.                               *
      *****************************************************************

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TABLE-OF-GROUP-ITEMS.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME          PIC X(15) VARYING.
       01  PASSWD            PIC X(15) VARYING.
       01  EMP-REC-TABLE OCCURS 5 TIMES.
           05  EMP-NUMBER    PIC S9(4) COMP.
           05  SALARY        PIC S9(6)V99
                             DISPLAY SIGN LEADING SEPARATE.
           05  EMP-NAME      PIC X(10) VARYING.
           EXEC SQL VAR SALARY IS DISPLAY(8,2) END-EXEC.
           EXEC SQL END DECLARE SECTION END-EXEC.
           EXEC SQL INCLUDE SQLCA END-EXEC.
       01  NUM-RET           PIC S9(9) COMP VALUE ZERO.
       01  PRINT-NUM         PIC S9(9) COMP VALUE ZERO.
       01  COUNTER           PIC S9(9) COMP.
       01  DISPLAY-VARIABLES.
           05  D-EMP-NAME    PIC X(10).
           05  D-EMP-NUMBER  PIC 9(4).
           05  D-SALARY      PIC Z(4)9.99.

       PROCEDURE DIVISION.

       BEGIN-PGM.
           EXEC SQL 
               WHENEVER SQLERROR DO PERFORM SQL-ERROR
           END-EXEC.
           PERFORM LOGON.
           EXEC SQL 
               DECLARE C1 CURSOR FOR
               SELECT EMPNO, SAL, ENAME 
               FROM EMP
           END-EXEC.
           EXEC SQL
               OPEN C1
           END-EXEC.

       FETCH-LOOP.
           EXEC SQL 
               WHENEVER NOT FOUND DO PERFORM SIGN-OFF
           END-EXEC.
           EXEC SQL 
               FETCH C1 
               INTO :EMP-REC-TABLE
           END-EXEC.
           SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
           PERFORM PRINT-IT.
           MOVE SQLERRD(3) TO NUM-RET.
           GO TO FETCH-LOOP.

       LOGON.
           MOVE "SCOTT" TO USERNAME-ARR.
           MOVE 5 TO USERNAME-LEN.
           MOVE "TIGER" TO PASSWD-ARR.
           MOVE 5 TO PASSWD-LEN.
           EXEC SQL
              CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
           DISPLAY " ".
           DISPLAY "CONNECTED TO ORACLE AS USER:  ", USERNAME-ARR.

       PRINT-IT.
           DISPLAY " ".
           DISPLAY "EMPLOYEE NUMBER  SALARY   EMPLOYEE NAME".
           DISPLAY "---------------  -------  -------------".
           PERFORM PRINT-ROWS
               VARYING COUNTER FROM 1 BY 1
               UNTIL COUNTER > PRINT-NUM.

       PRINT-ROWS.      
           MOVE EMP-NUMBER(COUNTER) TO D-EMP-NUMBER.
           MOVE SALARY(COUNTER) TO D-SALARY.
           DISPLAY "           ", D-EMP-NUMBER, " ", D-SALARY, "  ",
               EMP-NAME-ARR IN EMP-NAME(COUNTER).
           MOVE SPACES TO EMP-NAME-ARR IN EMP-NAME(COUNTER).

       SIGN-OFF.
           SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
           IF (PRINT-NUM > 0) PERFORM PRINT-IT.
           EXEC SQL 
               CLOSE C1 
           END-EXEC. 
           EXEC SQL 
               COMMIT WORK RELEASE 
           END-EXEC.
           DISPLAY " ".
           DISPLAY "HAVE A GOOD DAY.".
           DISPLAY " ".
           STOP RUN.

       SQL-ERROR.
           EXEC SQL 
               WHENEVER SQLERROR CONTINUE 
           END-EXEC.
           DISPLAY " ".
           DISPLAY "ORACLE ERROR DETECTED:".
           DISPLAY " ".
           DISPLAY SQLERRMC.
           EXEC SQL 
               ROLLBACK WORK RELEASE 
           END-EXEC.
           STOP RUN.
 

Additional Array Insert/Select Syntax

The Oracle precompiler also supports the DB2 insert and fetch syntax for the host tables. The supported additional array insert and fetch syntax are shown in the following images, respectively.

Figure 7-1 Additional Insert Syntax

Additional Insert Syntax

Figure 7-2 Additional Fetch Syntax

Additional Fetch Syntax

The optional ROWSET and ROWSET STARTING AT clauses are used in the fetch-orientation (FIRST, PRIOR, NEXT, LAST, CURRENT, RELATIVE and ABSOLUTE). Consider the following examples:

Examples of the DB2 array insert/fetch syntax and their comparison with the corresponding Oracle precompiler syntax are shown in Table 7-3:

Table 7-3 DB2 Array Syntax vs. Oracle Precompiler Syntax

DB2 Array SyntaxOracle Precompiler Syntax
EXEC SQL
  INSERT INTO DSN8810.ACT 
  (ACTNO, ACTKWD, ACTDESC) 
  VALUES (:HVA1, :HVA2, :HVA3)
  FOR :NUM_ROWS ROWS  
END-EXEC.
EXEC SQL FOR :NUM_ROWS
  INSERT INTO DSN8810.ACT
  (ACTNO, ACTKWD, ACTDESC)
  VALUES (:HVA1, :HVA2, :HVA3)
END-EXEC.
EXEC SQL
  FETCH NEXT ROWSET FROM C1 
  FOR 20 ROWS 
  INTO :HVA_EMPNO, :HVA_LASTNAME, 
       :HVA_SALARY 
END-EXEC.
EXEC SQL
   FOR :TWENTY
   FETCH c1 
   INTO :HVA_EMPNO, :HVA_LASTNAME,
        :HVA_SALARY
END-EXEC.

In DB2 syntax, a row-set positioned cursor should be first declared before retrieving row sets of data. To enable a cursor to fetch row sets, 'WITH ROWSET POSITIONING' clause has to be used in the DECLARE CURSOR statement, which is not required and relevant in the Oracle precompiler syntax, as shown in the following table.

DB2 Array SyntaxOracle Precompiler Syntax
EXEC SQL
 DECLARE C1 CURSOR
  WITH ROWSET POSITIONING FOR
  SELECT EMPNO, LASTNAME, SALARY
      FROM DSN8810.EMP
END-EXEC.
EXEC SQL
   DECLARE C1 CURSOR FOR
   SELECT EMPNO, LASTNAME, SALARY
        FROM DSN8810.EMP
END-EXEC.

This additional array syntax support can be enabled with the precompiler option "db2_array", whose default option is "no". The DB2 array syntax support cannot be used together with the Oracle precompiler syntax; only one of the syntax, either Oracle precompiler, or DB2 syntax, will be supported at a time.

Example 7-1 Inserting and Fetching Rows by Using the DB2 Array Syntax

This program inserts INSCNT rows into the EMP table by using the DB2 array insert syntax, and then fetches the inserted rows by using the DB2 array fetch syntax.

      *****************************************************************
      * db2arrdemo:                                                   *
      *****************************************************************
 
       IDENTIFICATION DIVISION.
       PROGRAM-ID.  db2arrdemo.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
 
      * EMBEDDED COBOL (file "DB2ARRDEMO.PCO")  
 
           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME          PIC X(10) VARYING.
       01  PASSWD            PIC X(10) VARYING.
       01  EMPINDATA.
           02  EMPIN OCCURS 25 TIMES.
              03  EMPNO PIC  9(4) COMP.
              03  ENAME PIC  X(10).
              03  JOB PIC  X(9).
              03  MGR PIC 9(4).
              03  HIREDATE PIC  X(9).
              03  SAL PIC  X(6).
              03  COMM PIC  X(6).
              03  DEPTNO PIC  9(2).
 
       01  EMPOUTDATA.
           02  EMPOUT OCCURS 5 TIMES.
              03  EMPNO1 PIC  9(4) COMP.
              03  ENAME1 PIC  X(10).
              03  JOB1 PIC  X(9).
              03  MGR1 PIC 9(4).
              03  HIREDATE1 PIC  X(9).
              03  SAL1 PIC  X(6).
              03  COMM1 PIC  X(6).
              03  DEPTNO1 PIC  9(2).
 
           EXEC SQL END DECLARE SECTION END-EXEC.
 
       01  INSCNT PIC  9(3) COMP VALUE 25.
       01  FETCHCNT PIC  9(3) COMP VALUE 5.
       01  CNT PIC  9(4).
       01  CNT2 PIC  9(2).
 
       01  STRINGFIELDS.
           02 STR PIC X(18) VARYING.
 
           EXEC SQL INCLUDE SQLCA END-EXEC.
 
       PROCEDURE DIVISION.
       BEGIN-PGM.
           EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.
 
           PERFORM LOGON.
 
      * Fill the array elements to insert.
   PERFORM FILL-DATA VARYING CNT FROM 1 BY 1 
           UNTIL CNT > INSCNT.
 
      * Inserting data using DB2 array insert syntax.
   DISPLAY "Inserting data using DB2 array insert syntax".
   EXEC SQL INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE,
            SAL, COMM, DEPTNO) VALUES (:EMPIN)
    FOR :INSCNT ROWS
   END-EXEC.
 
   EXEC SQL SELECT COUNT(*) INTO :CNT FROM EMP
            WHERE ENAME LIKE 'EMP_%'
   END-EXEC.
   DISPLAY "Number of rows successfully inserted into EMP "
           "table:", CNT.
 
   DISPLAY " ".
      * Declares scrollable cursor to fetch data.
           EXEC SQL DECLARE C1 SCROLL CURSOR FOR
                    SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL,
    COMM, DEPTNO 
    FROM EMP
            WHERE ENAME LIKE 'EMP_%'
    ORDER BY EMPNO
   END-EXEC.
 
           EXEC SQL OPEN C1 END-EXEC.
 
   DISPLAY "Fetching data using DB2 array fetch syntax ". 
         PERFORM FETCH-TAB.
       ENDFETCH-TAB.
 
   EXEC SQL CLOSE C1 END-EXEC.
 
           EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
           STOP RUN.
 
       LOGON.
           MOVE "scott" TO USERNAME-ARR.
           MOVE 5 TO USERNAME-LEN.
           MOVE "tiger" TO PASSWD-ARR.
           MOVE 5 TO PASSWD-LEN.
           EXEC SQL
               CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
 
      * FILLS ARRAY TO INSERT INTO EMP TABLE
       FILL-DATA.
           MOVE CNT TO EMPNO(CNT).
 
   MOVE " " TO STR.
   STRING "EMP_", CNT INTO STR
   END-STRING.
   MOVE STR TO ENAME(CNT).
 
   MOVE " " TO STR.
   STRING "JOB_", CNT INTO STR
   END-STRING.
   MOVE STR TO JOB(CNT).
 
   MOVE 100 TO MGR(CNT).
 
   IF CNT > 30 THEN
       COMPUTE CNT2 = 30
   ELSE 
       MOVE CNT TO CNT2
   END-IF
 
   MOVE " " TO STR.
   STRING CNT2, "-JAN-06" INTO STR
   END-STRING.
   MOVE STR TO HIREDATE(CNT).
 
   MOVE " " TO STR.
   STRING CNT2, "000" INTO STR
   END-STRING.
   MOVE STR TO SAL(CNT).
 
   MOVE 1000 TO COMM(CNT).
 
   MOVE 10 TO DEPTNO(CNT).
 
      * FETCHES DATA FROM EMP TABLE
       FETCH-TAB.
           EXEC SQL WHENEVER NOT FOUND GOTO ENDFETCH-TAB END-EXEC.
   DISPLAY "Fetch using FETCH FIRST ROWSET". 
           EXEC SQL FETCH FIRST ROWSET FROM C1 FOR :FETCHCNT ROWS 
            INTO :EMPOUT
   END-EXEC.
   PERFORM PRINTDATA.
 
   DISPLAY " ".
   DISPLAY "Fetch using FETCH NEXT ROWSET". 
           EXEC SQL FETCH NEXT ROWSET FROM C1 FOR 5 ROWS 
            INTO :EMPOUT END-EXEC.
   PERFORM PRINTDATA.
 
   DISPLAY " ".
   DISPLAY "Fetch using FETCH CURRENT ROWSET". 
           EXEC SQL FETCH CURRENT ROWSET FROM C1 FOR :FETCHCNT ROWS 
            INTO :EMPOUT
   END-EXEC.
   PERFORM PRINTDATA.
 
   DISPLAY " ".
   DISPLAY "Fetch using FETCH LAST ROWSET". 
           EXEC SQL FETCH LAST ROWSET FROM C1 FOR :FETCHCNT ROWS 
            INTO :EMPOUT
   END-EXEC.
   PERFORM PRINTDATA.
 
   DISPLAY " ".
   DISPLAY "Fetch using FETCH ROWSET STARTING AT ABSOLUTE". 
   COMPUTE CNT = 4 * FETCHCNT.
           EXEC SQL FETCH ROWSET STARTING AT ABSOLUTE :CNT FROM C1
            FOR 5 ROWS INTO :EMPOUT
   END-EXEC.
   PERFORM PRINTDATA.
 
   DISPLAY " ".
   DISPLAY "Fetch using FETCH ROWSET STARTING AT RELATIVE". 
           EXEC SQL FETCH ROWSET STARTING AT RELATIVE -3 FROM C1
            FOR :FETCHCNT ROWS INTO :EMPOUT
   END-EXEC.
   PERFORM PRINTDATA.
 
   DISPLAY " ".
   DISPLAY "Fetch using FETCH PRIOR ROWSET ". 
           EXEC SQL FETCH PRIOR ROWSET FROM C1 FOR :FETCHCNT ROWS 
            INTO :EMPOUT
   END-EXEC.
   PERFORM PRINTDATA.
 
      * Prints fetched data
       PRINTDATA.
   PERFORM VARYING CNT FROM 1 BY 1 UNTIL CNT > FETCHCNT
             DISPLAY "Empno=", EMPNO1(CNT), ", Ename=", ENAME1(CNT),
             ", Job=", JOB1(CNT), ", Mgr=", MGR1(CNT),
                     ", Hiredate=", HIREDATE1(CNT)
             DISPLAY "Sal=", SAL1(CNT), ", Comm=", COMM1(CNT),
             ", Deptno=", DEPTNO1(CNT)
           END-PERFORM.
 
      * HANDLES SQL ERROR CONDITIONS
       SQL-ERROR.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
           DISPLAY " ".
           DISPLAY "ORACLE ERROR DETECTED:".
           DISPLAY " ".
           DISPLAY SQLERRMC.
           EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
           STOP RUN.

Using Implicit Buffered Insert

For improved performance, Pro*Cobol application developers can reference host arrays in their embedded SQL statements. This provides a means to execute an array of SQL statements with a single round-trip to the database. Despite the significant performance improvements afforded by array execution, some developers choose not to use this capability because it is not ANSI standard. For example, an application written to exploit array execution in Oracle cannot be precompiled using IBM's precompiler.

One workaround is to use buffered INSERT statements, which enable you to gain performance benefits while retaining ANSI standard embedded SQL syntax.

The command line option "max_row_insert" controls the number of rows to be buffered before executing the INSERT statement. By default it is zero and the feature is disabled. To enable this feature, specify any number greater than zero.

If insert bufering is enabled, precompiler runtime will flag the corresponding cursor and:

If you are executing a new embedded SQL statement that results in a flush of the buffered insert statements:

The application is informed of the error through the standard precompiler error mechanisms such as SQLCODE or SQLSTATE in Pro*Cobol.

The "implicit_svpt" option controls whether an implicit savepoint is taken prior to the start of a new batched insert.

The following are some of the possible errors that you might face during buffered insert:

Example 7-2 inserting Buffered Rows into a Table

This program inserts LOOPCNT number of rows into the EMP table. At loop counter=5, this program attempts to insert an invalid empno. Without the max_row_insert option, the program inserts all rows except the invalid row. When the max_row_insert option is set to LOOPCNT, only the first four rows are inserted.

Using the max_row_insert option, when the erroneous statement is removed, the program performs the same way an array insert program would.

 *****************************************************************
      * bufinsdemo:                                                   *
      *                                                               *
      * This program inserts LOOPCNT number of rows into EMP table.   *
      * At loop counter=5, this program attempts to insert an invalid *
      * empno. Without max_row_insert option, this program inserts    *
      * all rows except this invalid row. When max_row_insert option  *
      * is set to LOOPCNT, only the first 4 rows are inserted.        *
      *                                                               *
      * With max_row_insert option, when this errorneous statement    *
      * is removed, the performance of this program is similar to     *
      * having an array insert in this program.                       *
      *****************************************************************
 
       IDENTIFICATION DIVISION.
       PROGRAM-ID.  bufinsdemo.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
 
      * EMBEDDED COBOL (file "BUFINSDEMO.PCO")  
 
           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME          PIC X(10) VARYING.
       01  PASSWD            PIC X(10) VARYING.
 
       01  EMPIN.
           02  EMPNO PIC  9(6) COMP.
           02  ENAME PIC  X(10).
           02 JOB PIC  X(9).
           02  MGR PIC 9(4).
           02  HIREDATE PIC  X(9).
           02  SAL PIC  X(6).
           02  COMM PIC  X(6).
           02  DEPTNO PIC  9(2).
 
       01  EMPOUT.
           02  EMPNO1 PIC  9(4) COMP.
           02  ENAME1 PIC  X(10).
           02  JOB1 PIC  X(9).
           02  MGR1 PIC 9(4).
           02  HIREDATE1 PIC  X(9).
           02  SAL1 PIC  X(6).
           02  COMM1 PIC  X(6).
           02  DEPTNO1 PIC  9(2).
 
           EXEC SQL END DECLARE SECTION END-EXEC.
 
       01  LOOPCNT PIC  9(4) COMP VALUE 100.
       01  CNT PIC  9(4).
       01  CNT2 PIC  9(2).
 
       01  STRINGFIELDS.
           02 STR PIC X(18) VARYING.
 
           EXEC SQL INCLUDE SQLCA END-EXEC.
 
       PROCEDURE DIVISION.
       BEGIN-PGM.
           EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.
 
           PERFORM LOGON.
 
      * When max_row_insert option is set to LOOPCNT and when the errorneous
      * statement is removed, all the rows will be inserted into the database
      * in one stretch and hence maximum performance gain will be achieved.
   DISPLAY "Inserting ", LOOPCNT, " rows into EMP table".
   PERFORM INS-TAB VARYING CNT FROM 1 BY 1 
           UNTIL CNT > LOOPCNT.
 
   EXEc SQL COMMIT END-EXEC.
 
   EXEC SQL SELECT COUNT(*) INTO :CNT FROM EMP
            WHERE ENAME LIKE 'EMP_%'
   END-EXEC.
   DISPLAY "Number of rows successfully inserted into EMP "
           "table:", CNT.
 
   DISPLAY " ".
           EXEC SQL DECLARE C1 CURSOR FOR
                    SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL,
    COMM, DEPTNO 
    FROM EMP
            WHERE ENAME LIKE 'EMP_%'
    ORDER BY EMPNO
   END-EXEC.
 
           EXEC SQL OPEN C1 END-EXEC.
 
   DISPLAY "Fetching inserted rows from EMP table". 
           PERFORM FETCH-TAB.
       ENDFETCH-TAB.
 
   EXEC SQL CLOSE C1 END-EXEC.
 
   EXEC SQL DELETE FROM EMP WHERE EMPNO < 1000 END-EXEC.
 
           EXEC SQL COMMIT WORK RELEASE END-EXEC.
           STOP RUN.
 
       LOGON.
           MOVE "scott" TO USERNAME-ARR.
           MOVE 5 TO USERNAME-LEN.
           MOVE "tiger" TO PASSWD-ARR.
           MOVE 5 TO PASSWD-LEN.
           EXEC SQL
               CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
 
      * INSERTS DATA INTO EMP TABLE
       INS-TAB.
   IF CNT = 5 THEN
     MOVE 10000 TO EMPNO
   ELSE
             MOVE CNT TO EMPNO
   END-IF
 
   MOVE " " TO STR.
   STRING "EMP_", CNT INTO STR
   END-STRING.
   MOVE STR TO ENAME.
 
   MOVE " " TO STR.
   STRING "JOB_", CNT INTO STR
   END-STRING.
   MOVE STR TO JOB.
 
   MOVE 100 TO MGR.
 
   IF CNT > 30 THEN
       COMPUTE CNT2 = 30
   ELSE 
       MOVE CNT TO CNT2
   END-IF
 
   MOVE " " TO STR.
   STRING CNT2, "-JAN-06" INTO STR
   END-STRING.
   MOVE STR TO HIREDATE.
 
   MOVE " " TO STR.
   STRING CNT2, "000" INTO STR
   END-STRING.
   MOVE STR TO SAL.
 
   MOVE 1000 TO COMM.
 
   MOVE 10 TO DEPTNO.
 
   EXEC SQL INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE,
            SAL, COMM, DEPTNO) VALUES (:EMPIN)
   END-EXEC.
 
      * FETCHES DATA FROM EMP TABLE
       FETCH-TAB.
           EXEC SQL WHENEVER NOT FOUND GOTO ENDFETCH-TAB END-EXEC.
           EXEC SQL FETCH C1 INTO :EMPOUT END-EXEC.
           DISPLAY "Empno=", EMPNO1, ", Ename=", ENAME1,
 ", Job=", JOB1, ", Mgr=", MGR1,
                   ", Hiredate=", HIREDATE1.
           DISPLAY "Sal=", SAL1, ", Comm=", COMM1, ", Deptno=", DEPTNO1.
 GO TO FETCH-TAB.
 
      * HANDLES SQL ERROR CONDITIONS
       SQL-ERROR.
           DISPLAY "ORACLE ERROR DETECTED:".
           DISPLAY SQLERRMC.
PK{.S&;,PKFJOEBPS/pco11ody.htm Oracle Dynamic SQL: Method 4

11 Oracle Dynamic SQL: Method 4

This chapter shows you how to implement Oracle dynamic SQL Method 4, which lets your program accept or build dynamic SQL statements that contain a varying number of host variables.

New applications should be developed using the newer ANSI SQL Method 4 described in Chapter 10, "ANSI Dynamic SQL".The ANSI Method 4 supports all Oracle types, while the older Oracle Method 4 does not support cursor variables, tables of group items, the DML returning clause, and LOBs.

Subjects discussed include the following:


Note:

For a discussion of dynamic SQL Methods 1, 2, and 3, and an overview of Oracle Method 4, see Chapter 9, "Oracle Dynamic SQL"

Meeting the Special Requirements of Method 4

Before looking into the requirements of Method 4, you should be familiar with the terms select-list item and place-holder. Select-list items are the columns or expressions following the keyword SELECT in a query. For example, the following dynamic query contains three select-list items:

SELECT ENAME, JOB, SAL + COMM FROM EMP WHERE DEPTNO = 20

Place-holders are dummy bind (input) variables that hold places in a SQL statement for actual bind variables. You do not declare place-holders and can name them anything you like. Place-holders for bind variables are most often used in the SET, VALUES, and WHERE clauses. For example, the following dynamic SQL statements each contain two place-holders.

INSERT INTO EMP (EMPNO, DEPTNO) VALUES (:E, :D)
DELETE FROM DEPT WHERE DEPTNO = :DNUM AND LOC = :DLOC

Place-holders cannot reference table or column names.

Advantages of Method 4

Unlike Methods 1, 2, and 3, dynamic SQL Method 4 lets your program:

  • Accept or build dynamic SQL statements that contain an unknown number of select-list items or place-holders

  • Take explicit control over datatype conversion between Oracle and COBOL types

To add this flexibility to your program, you must give the runtime library additional information.

Information the Database Needs

Pro*COBOL generates calls to Oracle for all executable dynamic SQL statements. If a dynamic SQL statement contains no select-list items or place-holders, the database needs no additional information to execute the statement. The following DELETE statement falls into this category:

*    Dynamic SQL statement...
     MOVE 'DELETE FROM EMP WHERE DEPTNO = 30' TO STMT.

However, most dynamic SQL statements contain select-list items or place-holders for bind variables, as shown in the following UPDATE statement:

*    Dynamic SQL statement with place-holders...
     MOVE 'UPDATE EMP SET COMM = :C WHERE EMPNO = :E' TO STMT.

To execute a dynamic SQL statement that contains select-list items or place-holders for bind variables, or both, the database needs information about the program variables that will hold output or input values. Specifically, the database needs the following information:

  • The number of select-list items and the number of bind variables

  • The length of each select-list item and bind variable

  • The datatype of each select-list item and bind variable

  • The memory address of each output variable that will store the value of a select-list item, and the address of each bind variable

For example, to write the value of a select-list item, the database needs the address of the corresponding output variable.

Where the Information is Stored

All the information the database needs about select-list items or place-holders for bind variables, except their values, is stored in a program data structure called the SQL Descriptor Area (SQLDA).

Descriptions of select-list items are stored in a select SQLDA, and descriptions of place-holders for bind variables are stored in a bind SQLDA.

The values of select-list items are stored in output buffers; the values of bind variables are stored in input buffers. You use the library routine SQLADR to store the addresses of these data buffers in a select or bind SQLDA, so that the database knows where to write output values and read input values.

How do values get stored in these data variables? A FETCH generates output values using a cursor, and input values are filled in by your program, typically from information entered interactively by the user.

How Information is Obtained

You use the DESCRIBE statement to help get the information the database needs. The DESCRIBE SELECT LIST statement examines each select-list item to determine its name, datatype, constraints, length, scale, and precision, then stores this information in the select SQLDA for your use. For example, you might use select-list names as column headings in a printout. DESCRIBE also stores the total number of select-list items in the SQLDA.

The DESCRIBE BIND VARIABLES statement examines each place-holder to determine its name and length, then stores this information in an input buffer and bind SQLDA for your use. For example, you might use place-holder names to prompt the user for the values of bind variables.

Understanding the SQL Descriptor Area (SQLDA)

This section describes the SQLDA data structure in detail. You learn how to declare it, what variables it contains, how to initialize them, and how to use them in your program.

Purpose of the SQLDA

Method 4 is required for dynamic SQL statements that contain an unknown number of select-list items or place-holders for bind variables. To process this kind of dynamic SQL statement, your program must explicitly declare SQLDAs, also called descriptors. Each descriptor corresponds to a group item in your program.

A select descriptor stores descriptions of select-list items and the addresses of output buffers that hold the names and values of select-list items.


Note:

The name of a select-list item can be a column name, a column alias, or the text of an expression such as SAL + COMM.

A bind descriptor stores descriptions of bind variables and indicator variables and the addresses of input buffers where the names and values of bind variables and indicator variables are stored.

Remember, some descriptor variables contain addresses, not values. Therefore, you must declare data buffers to hold the values. You decide the sizes of the required input and output buffers. Because COBOL does not support pointers, you must use the library subroutine SQLADR to get the addresses of input and output buffers. You learn how to call SQLADR in the section "Using SQLADR".

Multiple SQLDAs

If your program has more than one active dynamic SQL statement, each statement must have its own SQLDA. You can declare any number of SQLDAs with different names. For example, you might declare three select SQLDAs named SELDSC1, SELDSC2, and SELDSC3, so that you can FETCH from three concurrently open cursors. However, non-concurrent cursors can reuse SQLDAs.

Declaring a SQLDA

To declare select and bind SQLDAs, you can code them into your program using the sample select and bind SQLDAs shown in Figure 11-1. You can modify the table dimensions to suit your needs.


Note:

For byte-swapped platforms, use COMP5 instead of COMP when declaring a SQLDA.

Figure 11-1 Sample Pro*COBOL SQLDA Descriptors and Data Buffers (32 bit)

Sample Descriptors and Buffers


Note:

For 64-bit platforms, use PIC S9(18) declarations instead of PIC S9(9) when declaring a SQLDA.

You can store the SQLDAs in files (named SELDSC and BNDDSC, for example), and then copy the files into your program with the INCLUDE statement as follows:

     EXEC SQL INCLUDE SELDSC END-EXEC.
     EXEC SQL INCLUDE BNDDSC END-EXEC.

Figure 11-2 shows whether variables are set by SQLADR calls, DESCRIBE commands, FETCH commands, or program assignments.

Figure 11-2 How Variables Are Set

Setting Variables

The SQLDA Variables

This section explains the purpose and use of each variable in the SQLDA.

SQLDNUM

This variable specifies the maximum number of select-list items or place-holders that can be included in DESCRIBE. Thus, SQLDNUM determines the number of elements in the descriptor tables.

Before issuing a DESCRIBE command, you must set this variable to the dimension of the descriptor tables. After the DESCRIBE, you must reset it to the actual number of variables in the DESCRIBE, which is stored in SQLDFND.

SQLDFND

The SQLDFND variable is the actual number of select-list items or place-holders found by the DESCRIBE command.

SQLDFND is set by DESCRIBE. If SQLDFND is negative, the DESCRIBE command found too many select-list items or place-holders for the size of the descriptor. For example, if you set SQLDNUM to 10 but DESCRIBE finds 11 select-list items or place-holders, SQLDFND is set to -11. If this happens, you cannot process the SQL statement without reallocating the descriptor.

After the DESCRIBE, you must set SQLDNUM equal to SQLDFND.

SELDV | BNDDV

The SELDV | BNDDV table contains the addresses of data buffers that store select-list or bind-variable values.

You must set the elements of SELDV or BNDDV using SQLADR.

Select Descriptors

The following statement

     EXEC SQL FETCH ... USING DESCRIPTOR ...

directs the database to store FETCHed select-list values in the data buffers addressed by SELDV(1) through SELDV(SQLDNUM). Thus, the database stores the Jth select-list value in SEL-DV(J).

Bind Descriptors

You must set the bind descriptors before issuing the OPEN command. The following statement

     EXEC SQL OPEN ... USING DESCRIPTOR ...

directs Oracle to execute the dynamic SQL statement using the bind-variable values addressed by BNDDV(1) through BNDDV(SQLDNUM). (Typically, the values are entered by the user.) The database finds the Jth bind-variable value in BND-DV(J).

SELDFMT | BNDDFMT

The SELDFMT | BNDDFMT table contains the addresses of data buffers that store select-list or bind-variable conversion format strings. You can currently use it only for COBOL packed decimals. The format for the conversion string is PP.+SS or PP.-SS where PP is the precision and SS is the scale. For definitions of precision and scale, see the section "Extracting Precision and Scale".

The use of format strings is optional. If you want a conversion format for the Jth select-list item or bind variable, set SELDFMT(J) or BNDDFMT(J) using SQLADR, then store the packed-decimal format (07.+02 for example) in SEL-DFMT or BND-DFMT. Otherwise, set SELDFMT(J) or BNDDFMT(J) to zero.

SELDVLN | BNDDVLN

The SELDVLN | BNDDVLN table contains the lengths of select-list variables or bind-variable values stored in the data buffers.

Select Descriptors

DESCRIBE SELECT LIST sets the table of lengths to the maximum expected for each select-list item. However, you might want to reset some lengths before issuing a FETCH command. FETCH returns at most n characters, where n is the value of SELDVLN(J) before the FETCH command.

The format of the length differs among datatypes. For CHAR select-list items, DESCRIBE SELECT LIST sets SELDVLN(J) to the maximum length in bytes of the select-list item. For NUMBER select-list items, scale and precision are returned respectively in the low and next-higher bytes of the variable. You can use the library routine SQLPRC to extract precision and scale values from SELDVLN. See the section "Extracting Precision and Scale".

You must reset SELDVLN(J) to the required length of the data buffer before the FETCH. For example, when coercing a NUMBER to a COBOL character string, set SELDVLN(J) to the precision of the number plus two for the sign and decimal point. When coercing a NUMBER to a COBOL floating point number, set SELDVLN(J) to the length of the appropriate floating point type on your system.

For more information about the lengths of coerced datatypes, see the section "Converting Data".

Bind Descriptors

You must set the Bind Descriptor lengths before issuing the OPEN command. For example, you can use the following statements to set the lengths of bind-variable character strings entered by the user:

 PROCEDURE DIVISION. 
     ... 
     PERFORM GET-INPUT-VAR 
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN BNDDSC. 
     ... 
 GET-INPUT-VAR. 
     DISPLAY "Enter value of ", BND-DH-VNAME(J). 
     ACCEPT INPUT-STRING. 
     UNSTRING INPUT-STRING DELIMITED BY "  " 
         INTO BND-DV(J) COUNT IN BNDDVLN(J). 

Because Oracle accesses a data buffer indirectly, using the address in SELDV(J) or BNDDV(J), it does not know the length of the value in that buffer. If you want to change the length Oracle uses for the Jth select-list or bind-variable value, reset SELDVLN(J) or BNDDVLN(J) to the length you need. Each input or output buffer can have a different length.

SELDFMTL | BNDDFMTL

This is a table containing the lengths of select-list or bind-variable conversion format strings. Currently, you can use it only for COBOL packed decimal.

The use of format strings is optional. If you want a conversion format for the Jth select-list item or bind variable, set SELDFMTL(J) before the FETCH or BNDDFMTL(J) before the OPEN to the length of the packed-decimal format stored in SEL-DFMT or BND-DFMT. Otherwise, set SELDFMTL(J) or BNDDFMTL(J) to zero.

If the value of SELDFMTL(J) or BNDDFMTL(J) is zero, SELDFMT(J) or BNDDFMT(J) are not used.

SELDVTYP | BNDDVTYP

The SELDVTYP | BNDDVTYP table contains the datatype codes of select-list or bind-variable values. These codes determine how Oracle data is converted when stored in the data buffers addressed by elements of SELDV. The datatype descriptor table is further described in "Converting Data".

Select Descriptors

DESCRIBE SELECT LIST sets the table of datatype codes to the internal datatype (for example, VARCHAR2, CHAR, NUMBER, or DATE) of the items in the select list.

Before a FETCH is executed, you might want to reset some datatypes because the internal format of datatypes can be difficult to handle. For display purposes, it is usually a good idea to coerce the datatype of select-list values to VARCHAR2. For calculations, you might want to coerce numbers from Oracle to COBOL format. See "Coercing Datatypes".

The high bit of SELDVTYP(J) is set to indicate the NULL/not NULL status of the Jth select-list column. You must always clear this bit before issuing an OPEN or FETCH command. Use the library routine SQLNUL to retrieve the datatype code and clear the NULL/not NULL bit. For more information, see: "Handling NULL/Not NULL Datatypes".

It is best to change the NUMBER internal datatype to an external datatype compatible with that of the COBOL data buffer addressed by SELDV(J).

Bind Descriptors

DESCRIBE BIND VARIABLES sets the table of datatype codes to zeros. You must reset the table of datatypes before issuing the OPEN command. The code represents the external (COBOL) datatype of the buffer addressed by BNDDV(J). Often, bind-variable values are stored in character strings, so the datatype table elements are set to 1 (the VARCHAR2 datatype code).

To change the datatype of the Jth select-list or bind-variable value, reset SELDVTYP(J) or BNDDVTYP(J) to the datatype you want.

SELDI | BNDDI

The SELDI | BNDDI table contains the addresses of data buffers that store indicator-variable values. You must set the elements of SELDI or BNDDI using SQLADR.

Select Descriptors

You must set this table before issuing the FETCH command. When Oracle executes the statement

     EXEC SQL FETCH ... USING DESCRIPTOR ... 

if the Jth returned select-list value is NULL, the buffer addressed by SELDI(J) is set to -1. Otherwise, it is set to zero (the value is not NULL) or a positive integer (the value was truncated).

Bind Descriptors

You must initialize this table and set the associated indicator variables before issuing the OPEN command. When Oracle executes the statement

     EXEC SQL OPEN ... USING DESCRIPTOR ...

the buffer addressed by BNDDI(J) determines whether the Jth bind variable is NULL. If the value of an indicator variable is -1, its associated bind variable is NULL.

SELDH-VNAME | BNDDH-VNAME

The SELDH-VNAME | BNDDH-VNAME table contains the addresses of data buffers that store select-list or place-holder names as they appear in dynamic SQL statements. You must set the elements of SELDH-VNAME or BNDDH-VNAME using SQLADR before issuing the DESCRIBE command.

DESCRIBE directs Oracle to store the name of the Jth select-list item or place-holder in the data buffer addressed by SELDH-VNAME(J) or BNDDH-VNAME(J). Thus, Oracle stores the Jth select-list or place-holder name in SEL-DH-VNAME(J) or BND-DH-VNAME(J).


Note:

The SELDH-VNAME | BNDDH-VNAME table contains only the name of the column, and not the table-qualifier.column name, even if you provide it in your SQL statement. If, for example, you were to do a describe of select-list in the SQL statement select a.owner from all_tables the software will return not a.owner, but instead, owner. If necessary, you should use column aliases to correctly identify a column in the select list.

SELDH-MAX-VNAMEL | BNDDH-MAX-VNAMEL

The SELDH-MAX-VNAMEL | BNDDH-MAX-VNAMEL table contains the maximum lengths of the data buffers that store select-list or place-holder names. The buffers are addressed by the elements of SELDH-VNAME or BNDDH-VNAME.

You must set the elements of SELDH-MAX-VNAMEL or BNDDH-MAX-VNAMEL before issuing the DESCRIBE command. Each select-list or place-holder name buffer can have a different length.

SELDH-CUR-VNAMEL | BNDDH-CUR-VNAMEL

The SELDH-CUR-VNAMEL | BNDDH-CUR-VNAMEL table contains the actual lengths of the names of the select-list or place-holder. DESCRIBE sets the table of actual lengths to the number of characters in each select-list or place-holder name.

SELDI-VNAME | BNDDI-VNAME

The SELDI-VNAME | BNDDI-VNAME table contains the addresses of data buffers that store indicator-variable names.

You can associate indicator-variable values with select-list items and bind variables. However, you can associate indicator-variable names only with bind variables. You can use this table only with bind descriptors. You must set the elements of BNDDI-VNAME using SQLADR before issuing the DESCRIBE command.

DESCRIBE BIND VARIABLES directs Oracle to store any indicator-variable names in the data buffers addressed by BNDDI-VNAME(1) through BNDDI-VNAME(SQLDNUM). Thus, Oracle stores the Jth indicator-variable name in BND-DI-VNAME(J).

SELDI-MAX-VNAMEL | BNDDI-MAX-VNAMEL

The SELDI-MAX-VNAMEL | BNDDI-MAX-VNAMEL table contains the maximum lengths of the data buffers that store indicator-variable names. The buffers are addressed by the elements of SELDI-VNAME or BNDDI-VNAME.

You can associate indicator-variable names only with bind variables. You can use this table only with bind descriptors.

You must set the elements BNDDI-MAX-VNAMEL(1) through BNDDI-MAX-VNAMEL(SQLDNUM) before issuing the DESCRIBE command. Each indicator-variable name buffer can have a different length.

SELDI-CUR-VNAMEL | BNDDI-CUR-VNAMEL

The SELDI-CUR-VNAMEL | BNDDI-CUR-VNAMEL table contains the actual lengths of the names of the indicator variables. You can associate indicator-variable names only with bind variables. You can use this table only with bind descriptors.

DESCRIBE BIND VARIABLES sets the table of actual lengths to the number of characters in each indicator-variable name.

SELDFCLP | BNDDFCLP

The SELDFCLP | BNDDFCLP table is reserved for future use. It must be present because Oracle expects the group item SELDSC or BNDDSC to be a certain size. You must currently set the elements of SELDFCLP and BNDDFCLP to zero.

SELDFCRCP | BNDDFCRCP

The SELDFCRCP | BNDDFCRCP table is reserved for future use. It must be present because Oracle expects the group item SELDSC or BNDDSC to be a certain size. You must set the elements of SELDFCRCP and BNDDFCRCP to zero.

Prerequisite Knowledge

You need a working knowledge of the following subjects to implement dynamic SQL Method 4:

Using SQLADR

You must call the library subroutine SQLADR to get the addresses of data buffers that store input and output values. You store the addresses in a bind or select SQLDA so that Oracle knows where to read bind-variable values or write select-list values.

Call SQLADR using the syntax

     CALL "SQLADR" USING BUFFER, ADDRESS.

where:

BUFFER

Is a data buffer that stores the value or name of a select-list item, bind variable, or indicator variable.

ADDRESS

Is an integer variable that returns the address of the data buffer.

A call to SQLADR stores the address of BUFFER in ADDRESS. The next example uses SQLADR to initialize the select descriptor tables SELDV, SELDH-VNAME, and SELDI. Their elements address data buffers for select-list values, select-list names, and indicator values.

 PROCEDURE DIVISION.
     ... 
     PERFORM INIT-SELDSC 
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC.
     ... 
 INIT-SELDSC.
     CALL "SQLADR" USING SEL-DV(J), SELDV(J).
     CALL "SQLADR" USING SEL-DH-VNAME(J), SELDH-VNAME(J).
     CALL "SQLADR" USING SEL-DI(J), SELDI(J).

Converting Data

This section provides more detail about the datatype descriptor table. In host programs that use neither datatype equivalencing nor dynamic SQL Method 4, the conversion between internal and external datatypes is determined at precompile time. By default, Pro*COBOL assigns a specific external datatype to each host variable. For example, Pro*COBOL assigns the INTEGER external datatype to host variables of type PIC S9(n) COMP.

However, Method 4 lets you control data conversion and formatting. You specify conversions by setting datatype codes in the datatype descriptor table.

Internal Datatypes

Internal datatypes specify the formats used by Oracle to store column values in database tables to represent pseudocolumn values.

When you issue a DESCRIBE SELECT LIST command, Oracle returns the internal datatype code for each select-list item to the SELDVTYP (datatype) descriptor table. For example, the datatype code for the Jth select-list item is returned to SELDVTYP(J).

Table 11-1 shows the internal datatypes and their codes:

Table 11-1 Internal Datatypes and Related Codes

Internal DatatypeCode

VARCHAR2

NUMBER

LONG

ROWID

DATE

RAW

LONG RAW

CHAR

1

2

8

11

12

23

24

96


External Datatypes

External datatypes specify the formats used to store values in input and output host variables.

The DESCRIBE BIND VARIABLES command sets the BNDDVTYP table of datatype codes to zeros. Therefore, you must reset the codes before issuing the OPEN command. The codes tell Oracle which external datatypes to expect for the various bind variables. For the Jth bind variable, reset BNDDVTYP(J) to the external datatype you want.

The following table shows the external datatypes and their codes, as well as the corresponding COBOL datatypes:

Table 11-2 Oracle External and Related COBOL Datatypes

NameCodeCOBOL Datatype

VARCHAR2

1

PIC X(n) when MODE=ANSI

NUMBER

2

PIC X(n)

INTEGER

3

PIC S9(n) COMP

(Use COMP, not COMP5, on SPARC Solaris 64 bit platforms)

PIC S9(n) COMP5

(COMP5 for byte-swapped platforms)

FLOAT

4

COMP-1

COMP-2

STRING (0)

5

PIC X(n)

VARNUM

6

PIC X(n)

DECIMAL

7

PIC S9(n)V9(n) COMP-3

LONG

8

PIC X(n)

VARCHAR (2)

9

PIC X(n) VARYING

PIC N(n) VARYING

ROWID

11

PIC X(n)

DATE

12

PIC X(n)

VARRAW (2)

15

PIC X(n)

RAW

23

PIC X(n)

LONG RAW

24

PIC X(n)

UNSIGNED

68

(not supported)

DISPLAY

91

PIC S9...9V9...9 DISPLAY SIGN LEADING SEPARATE

PIC S9(n)V9(n) DISPLAY SIGN LEADING SEPARATE

LONG VARCHAR (2)

94

PIC X(n)

LONG VARRAW (2)

95

PIC X(n)

CHARF

96

PIC X(n) when MODE = ANSI

PIC N(n) when MODE = ANSI

CHARZ (0)

97

PIC X(n)

CURSOR

102

SQL-CURSOR


Notes:

  1. For use in an EXEC SQL VAR statement only.

  2. Include the n-byte length field.

For more information about the datatypes and their formats, see "The Oracle Database 11g Datatypes".

PL/SQL Datatypes

PL/SQL provides a variety of predefined scalar and composite datatypes. A scalar type has no internal components. A composite type has internal components that can be manipulated individually. Table 11-4 shows the predefined PL/SQL scalar datatypes and their internal datatype equivalence

Table 11-3 PL/SQL Datatype Equivalences with Internal Datatypes

PL/SQL DatatypeOracle Internal Datatype

VARCHAR

VARCHAR2

VARCHAR2

BINARY_INTEGER

DEC

DECIMAL

DOUBLE PRECISION

FLOAT

INT

INTEGER

NATURAL

NUMBER

NUMERIC

POSITIVE

REAL

SMALLINT

NUMBER

LONG

LONG

ROWID

ROWID

DATE

DATE

RAW

RAW

LONG RAW

LONG RAW

CHAR

CHARACTER

STRING

CHAR


Coercing Datatypes

For a select descriptor, DESCRIBE SELECT LIST can return any of the internal datatypes. Often, as in the case of character data, the internal datatype corresponds exactly to the external datatype you want to use. However, a few internal datatypes map to external datatypes that can be difficult to handle. Thus, you might want to reset some elements in the SELDVTYP descriptor table.

For example, you might want to reset NUMBER values to FLOAT values, which correspond to PIC S9(n)V9(n) COMP-1 values in COBOL. Oracle does any necessary conversion between internal and external datatypes at FETCH time. Be sure to reset the datatypes after the DESCRIBE SELECT LIST but before the FETCH.

For a bind descriptor, DESCRIBE BIND VARIABLES does not return the datatypes of bind variables, only their number and names. Therefore, you must explicitly set the BNDDVTYP table of datatype codes to tell Oracle the external datatype of each bind variable. Oracle does any necessary conversion between external and internal datatypes at OPEN time.

When you reset datatype codes in the SELDVTYP or BNDDVTYP descriptor table, you are "coercing datatypes." For example, to coerce the Jth select-list value to VARCHAR2, use the following statement:

*    Coerce select-list value to VARCHAR2. 
     MOVE 1 TO SELDVTYP(J). 

When coercing a NUMBER select-list value to VARCHAR2 for display purposes, you must also extract the precision and scale bytes of the value and use them to compute a maximum display length. Then, before the FETCH, you must reset the appropriate element of the SELDVLN (length) descriptor table to tell Oracle the buffer length to use. To specify the length of the Jth select-list value, set SELDVLN(J) to the length you need.

For example, if DESCRIBE SELECT LIST finds that the Jth select-list item is of type NUMBER, and you want to store the returned value in a COBOL variable declared as PIC S9(n)V9(n) COMP-1, simply set SELDVTYP(J) to 4 and SELDVLN(J) to the length of COMP-1 numbers on your system.

Exceptions

In some cases, the internal datatypes that DESCRIBE SELECT LIST returns might not suit your purposes. Two examples of this are DATE and NUMBER. When you DESCRIBE a DATE select-list item, Oracle returns the datatype code 12 to the SELDVTYP table. Unless you reset the code before the FETCH, the date value is returned in its 7-byte internal format. To get the date in its default character format, you must change the datatype code from 12 to 1 (VARCHAR2) and increase the SELDVLN value from 7 to 9.

Similarly, when you DESCRIBE a NUMBER select-list item, Oracle returns the datatype code 2 to the SELDVTYP table. Unless you reset the code before the FETCH, the numeric value is returned in its internal format, which is probably not desired. Therefore, change the code from 2 to 1 (VARCHAR2), 3 (INTEGER), 4 (FLOAT), or some other appropriate datatype.

Extracting Precision and Scale

The library subroutine SQLPRC extracts precision and scale. Normally, it is used after the DESCRIBE SELECT LIST, and its first parameter is SELDVLN(J). To call SQLPRC, use the following syntax

     CALL "SQLPRC" USING LENGTH, PRECISION, SCALE.

where:

SyntaxDescription
LENGTHIs an integer variable that stores the length of a NUMBER value. The scale and precision of the value are stored in the low and next-higher bytes, respectively.
PRECISIONIs an integer variable that returns the precision of the NUMBER value. Precision is the number of significant digits. It is set to zero if the select-list item refers to a NUMBER of unspecified size. In this case, because the size is unspecified, assume the maximum precision, 38.
SCALEIs an integer variable that returns the scale of the NUMBER value. Scale specifies where rounding will occur. For example, a scale of 2 means the value is rounded to the nearest hundredth (3.456 becomes 3.46); a scale of -3 means that the number is rounded to the nearest thousand (3.456 becomes 3000).

The following example shows how SQLPRC is used to compute maximum display lengths for NUMBER values that will be coerced to VARCHAR2:

 WORKING-STORAGE SECTION. 
 01  PRECISION       PIC S9(9) COMP. 
 01  SCALE           PIC S9(9) COMP. 
 01  DISPLAY-LENGTH  PIC S9(9) COMP. 
 01  MAX-LENGTH      PIC S9(9) COMP VALUE 80. 
     ... 
 PROCEDURE DIVISION. 
     ... 
     PERFORM ADJUST-LENGTH 
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC. 
 ADJUST-LENGTH. 
*    If datatype is NUMBER, extract precision and scale. 
     IF SELDVTYP(J) = 2 
         CALL "SQLPRC" USING SELDVLN(J), PRECISION, SCALE. 
     MOVE 0 TO DISPLAY-LENGTH. 
*    Precision is set to zero if the select-list item 
*    refers to a NUMBER of unspecified size.  We allow for 
*    a maximum precision of 10. 
     IF SELDVTYP(J) = 2 AND PRECISION = 0 
         MOVE 10 TO DISPLAY-LENGTH. 
*    Allow for possible decimal point and sign. 
     IF SELDVTYP(J) = 2 AND PRECISION > 0 
         ADD 2 TO PRECISION 
         MOVE PRECISION TO DISPLAY-LENGTH. 
     ... 

Notice that the first parameter in the subroutine call is the Jth element in the table of select-list lengths.

The SQLPRC procedure, defined in the SQLLIB runtime library, returns zero as the precision and scale values for certain SQL datatypes. The SQLPR2 procedure is similar to SQLPRC in that it has the same syntax and returns the same binary values, except for the datatypes shown in this table:

Table 11-4 Datatype Exceptions to the SQLPR2 Procedure

SQL DatatypeBinary PrecisionBinary Scale

FLOAT

126

-127

FLOAT(n)

n (range is 1 .. 126)

-127

REAL

63

-127

DOUBLE PRECISION

126

-127


Handling NULL/Not NULL Datatypes

For every select-list column (not expression), DESCRIBE SELECT LIST returns a NULL/not NULL indication in the datatype table of the select descriptor. If the Jth select-list column is constrained to be not NULL, the high-order bit of SELDVTYP(J) datatype variable is clear; otherwise, it is set.

Before using the datatype in an OPEN or FETCH statement, if the NULL status bit is set, you must clear it. Never set the bit.

You can use the library routine SQLNUL to find out if a column allows NULL datatypes and to clear the datatype's NULL status bit. You call SQLNUL using the syntax

     CALL "SQLNUL" USING VALUE-TYPE, TYPE-CODE, NULL-STATUS.

where:

SyntaxDescription
VALUE-TYPEIs a 2-byte integer variable that stores the datatype code of a select-list column.
TYPE-CODEIs a 2-byte integer variable that returns the datatype code of the select-list column with the high-order bit cleared.
NULL-STATUSIs an integer variable that returns the NULL status of the select-list column. 1 means that the column allows NULLs; 0 means that it does not.

The following example shows how to use SQLNUL:

 WORKING-STORAGE SECTION.
     ... 
*    Declare variable for subroutine call.
     01  NULL-STATUS  PIC S9(9) COMP.
     ... 
 PROCEDURE DIVISION.
 MAIN.
     EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.
     ...
     PERFORM HANDLE-NULLS
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC.
     ...
 HANDLE-NULLS.
*    Find out if column is NOT NULL, and clear high-order bit.
     CALL "SQLNUL" USING SELDVTYP(J), SELDVTYP(J), NULL-STATUS.
*    If NULL-STATUS = 1, NULLs are allowed.

Notice that the first and second parameters in the subroutine call are the same. Respectively, they are the datatype variable before and after its NULL status bit is cleared.

The Basic Steps

Method 4 can be used to process any dynamic SQL statement. In the example in "Using Host Tables with Method 4", a query is processed so that you can see how both input and output host variables are handled.

To process the dynamic query, our example program takes the following steps:

  1. Declare a host string to hold the query text.

  2. Declare select and bind descriptors.

  3. Set the maximum number of select-list items and place-holders that can be DESCRIBEd.

  4. Initialize the select and bind descriptors.

  5. Store the query text in the host string.

  6. PREPARE the query from the host string.

  7. DECLARE a cursor FOR the query.

  8. DESCRIBE the bind variables INTO the bind descriptor.

  9. Reset the number of place-holders to the number actually found by DESCRIBE.

  10. Get values for the bind variables found by DESCRIBE.

  11. OPEN the cursor USING the bind descriptor.

  12. DESCRIBE the select list INTO the select descriptor.

  13. Reset the number of select-list items to the number actually found by DESCRIBE.

  14. Reset the length and datatype of each select-list item for display purposes.

  15. FETCH a row from the database INTO data buffers using the select descriptor.

  16. Process the select-list values returned by FETCH.

  17. CLOSE the cursor when there are no more rows to FETCH.


Note:

If the dynamic SQL statement is not a query or contains a known number of select-list items or place-holders, then some of the preceding steps are unnecessary.

A Closer Look at Each Step

This section discusses each step in more detail. A full-length example program illustrating Method 4 is seen at the end of this chapter. With Method 4, you use the following sequence of embedded SQL statements:

     EXEC SQL
         PREPARE <statement_name>
         FROM {:<host_string> | <string_literal>}
     END-EXEC.
     EXEC SQL 
         DECLARE <cursor_name> CURSOR FOR <statement_name>
     END-EXEC.
     EXEC SQL
         DESCRIBE BIND VARIABLES FOR <statement_name>
         INTO <bind_descriptor_name>
     END-EXEC.
     EXEC SQL
         OPEN <cursor_name> 
         [USING DESCRIPTOR <bind_descriptor_name>]
     END-EXEC.
     EXEC SQL
         DESCRIBE [SELECT LIST FOR] <statement_name>
         INTO <select_descriptor_name>
     END-EXEC.
     EXEC SQL
         FETCH <cursor_name> USING DESCRIPTOR <select_descriptor_name>
     END-EXEC.
     EXEC SQL
         CLOSE <cursor_name>
     END-EXEC.

If the number of select-list items in a dynamic query is known, you can omit DESCRIBE SELECT LIST and use the following Method 3 FETCH statement:

EXEC SQL FETCH <cursor_name> INTO <host_variable_list> END-EXEC.

Alternatively, if the number of place-holders for bind variables in a dynamic SQL statement is known, you can omit DESCRIBE BIND VARIABLES and use the following Method 3 OPEN statement:

     EXEC SQL OPEN <cursor_name> [USING <host_variable_list>] END-EXEC.

The next section illustrates how these statements allow your host program to accept and process a dynamic SQL statement using descriptors.


Note:

Several figures accompany the following discussion. To avoid cluttering the figures, it was necessary to confine descriptor tables to 3 elements and to limit the maximum length of names and values to 5 and 10 characters, respectively.

Declare a Host String

Your program needs a host variable to store the text of the dynamic SQL statement. The host variable (SELECTSTMT in our example) must be declared as a character string:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
     ... 
 01  SELECTSTMT  PIC X(120). 
     EXEC SQL END DECLARE SECTION END-EXEC. 

Declare the SQLDAs

Because the query in our example might contain an unknown number of select-list items or place-holders, you must declare select and bind descriptors. Instead of hard-coding the SQLDAs, you use INCLUDE to copy them into your program, as follows:

     EXEC SQL INCLUDE SELDSC END-EXEC. 
     EXEC SQL INCLUDE BNDDSC END-EXEC. 

For reference, the INCLUDEd declaration of SELDSC follows:

 WORKING-STORAGE SECTION. 
     ... 
 01  SELDSC. 
         05  SQLDNUM              PIC S9(9) COMP. 
         05  SQLDFND              PIC S9(9) COMP. 
         05  SELDVAR              OCCURS 3 TIMES. 
             10 SELDV             PIC S9(9) COMP. 
             10 SELDFMT           PIC S9(9) COMP. 
             10 SELDVLN           PIC S9(9) COMP. 
             10 SELDFMTL          PIC S9(4) COMP. 
             10 SELDVTYP          PIC S9(4) COMP. 
             10 SELDI             PIC S9(9) COMP. 
             10 SELDH-VNAME       PIC S9(9) COMP. 
             10 SELDH-MAX-VNAMEL  PIC S9(4) COMP. 
             10 SELDH-CUR-VNAMEL  PIC S9(4) COMP. 
             10 SELDI-VNAME       PIC S9(9) COMP. 
             10 SELDI-MAX-VNAMEL  PIC S9(4) COMP. 
             10 SELDI-CUR-VNAMEL  PIC S9(4) COMP. 
             10 SELDFCLP          PIC S9(9) COMP. 
             10 SELDFCRCP         PIC S9(9) COMP. 

 01  XSELDI. 
     05  SEL-DI        OCCURS 3 TIMES PIC S9(9) COMP. 
 01  XSELDIVNAME. 
         05  SEL-DI-VNAME  OCCURS 3 TIMES PIC X(5). 
 01  XSELDV. 
         05  SEL-DV        OCCURS 3 TIMES PIC X(10). 
 01  XSELDHVNAME. 
         05  SEL-DH-VNAME  OCCURS 3 TIMES PIC X(5).  

Set the Maximum Number to DESCRIBE

You next set the maximum number of select-list items or place-holders that can be described, as follows:

     MOVE 3 TO SQLDNUM IN SELDSC. 
     MOVE 3 TO SQLDNUM IN BNDDSC. 

Initialize the Descriptors

You must initialize several descriptor variables. Some require the library subroutine SQLADR.

In our example, you store the maximum lengths of name buffers in the SELDH-MAX-VNAMEL, BNDDH-MAX-VNAMEL, and BNDDI-MAX-VNAMEL tables, and use SQLADR to store the addresses of value and name buffers in the SELDV, SELDI, BNDDV, BNDDI, SELDH-VNAME, BNDDH-VNAME, and BNDDI-VNAME tables.

 PROCEDURE DIVISION. 
     ... 
     PERFORM INIT-SELDSC 
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC. 
     PERFORM INIT-BNDDSC 
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN BNDDSC. 
     ... 
 INIT-SELDSC. 
     MOVE SPACES TO SEL-DV(J). 
     MOVE SPACES TO SEL-DH-VNAME(J). 
     MOVE 5 TO SELDH-MAX-VNAMEL(J). 
     CALL "SQLADR" USING SEL-DV(J), SELDV(J). 
     CALL "SQLADR" USING SEL-DH-VNAME(J), SELDH-VNAME(J). 
     CALL "SQLADR" USING SEL-DI(J), SELDI(J). 
     ... 
 INIT-BNDDSC. 
     MOVE SPACES TO BND-DV(J). 
     MOVE SPACES TO BND-DH-VNAME(J). 
     MOVE SPACES TO BND-DI-VNAME(J). 
     MOVE 5 TO BNDDH-MAX-VNAMEL(J). 
     MOVE 5 TO BNDDI-MAX-VNAMEL(J). 
     CALL "SQLADR" USING BND-DV(J), BNDDV(J). 
     CALL "SQLADR" USING BND-DH-VNAME(J), BNDDH-VNAME(J). 
     CALL "SQLADR" USING BND-DI(J), BNDDI(J). 
     CALL "SQLADR" USING BND-DI-VNAME(J), BNDDI-VNAME(J).
     ...

Figure 11-3 and Figure 11-4 represent the resulting descriptors.

Figure 11-3 Initialized Select Descriptor

Initialized Select Descriptor

Figure 11-4 Initialized Bind Descriptor

Initialized Bind Descriptor

Store the Query Text in the Host String

Next, you prompt the user for a SQL statement, then store the input string in SELECTSTMT as follows:

     DISPLAY "Enter a SELECT statement: " WITH NO ADVANCING. 
     ACCEPT SELECTSTMT. 

We assume the user entered the following string:

     SELECT ENAME, EMPNO, COMM FROM EMP WHERE COMM < :BONUS

PREPARE the Query from the Host String

PREPARE parses the SQL statement and gives it a name. In our example, PREPARE parses the host string SELECTSTMT and gives it the name SQLSTMT, as follows:

     EXEC SQL PREPARE SQLSTMT FROM :SELECTSTMT END-EXEC. 

DECLARE a Cursor

DECLARE CURSOR defines a cursor by giving it a name and associating it with a specific SELECT statement.

To declare a cursor for static queries, use the following syntax:

     EXEC SQL DECLARE cursor_name CURSOR FOR SELECT ... 

To declare a cursor for dynamic queries, the statement name given to the dynamic query by PREPARE replaces the static query. In our example, DECLARE CURSOR defines a cursor named EMPCURSOR and associates it with SQLSTMT, as follows:

     EXEC SQL DECLARE EMPCURSOR CURSOR FOR SQLSTMT END-EXEC.

Note:

You must declare a cursor for all dynamic SQL statements, not just queries. With non-queries, OPENing the cursor executes the dynamic SQL statement.

DESCRIBE the Bind Variables

DESCRIBE BIND VARIABLES puts descriptions of bind variables into a bind descriptor. In our example, DESCRIBE readies BNDDSC as follows:

     EXEC SQL 
         DESCRIBE BIND VARIABLES FOR SQLSTMT 
         INTO BNDDSC 
     END-EXEC. 

Note that BNDDSC must not be prefixed with a colon.

The DESCRIBE BIND VARIABLES statement must follow the PREPARE statement but precede the OPEN statement.

Figure 11-5 shows the bind descriptor in our example after the DESCRIBE. Notice that DESCRIBE has set SQLDFND to the actual number of place-holders found in the processed SQL statement.

Figure 11-5 Bind Descriptor after the DESCRIBE

Bind after DESCRIBE

Reset Number of Place-Holders

Next, you must reset the maximum number of place-holders to the number actually found by DESCRIBE, as follows:

     IF SQLDFND IN BNDDSC < 0 
         DISPLAY "Too many bind variables" 
         GOTO ROLL-BACK 
     ELSE 
         MOVE SQLDFND IN BNDDSC TO SQLDNUM IN BNDDSC
     END-IF. 

Get Values for Bind Variables

Your program must get values for the bind variables in the SQL statement. How the program gets the values is up to you. For example, they can be hard-coded, read from a file, or entered interactively.

In our example, a value must be assigned to the bind variable that replaces the place-holder BONUS in the query WHERE clause. Prompt the user for the value, then process it, as follows:

 PROCEDURE DIVISION. 
     ... 
     PERFORM GET-INPUT-VAR 
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN BNDDSC. 
     ... 
 GET-INPUT-VAR. 
     ... 
*    Replace the 0 DESCRIBEd into the datatype table 
*    with a 1 to avoid an "invalid datatype" Oracle error. 
     MOVE 1 TO BNDDVTYP(J). 
*    Get value of bind variable. 
     DISPLAY "Enter value of ", BND-DH-VNAME(J). 
     ACCEPT INPUT-STRING. 
     UNSTRING INPUT-STRING DELIMITED BY "  " 
         INTO BND-DV(J) COUNT IN BNDDVLN(J). 

Assuming that the user supplied a value of 625 for BONUS, the next table shows the resulting bind descriptor.

Figure 11-6 Bind Descriptor after Assigning Values

After Assigning

OPEN the Cursor

The OPEN statement for dynamic queries is similar to the one for static queries, except the cursor is associated with a bind descriptor. Values determined at run time and stored in buffers addressed by elements of the bind descriptor tables are used to evaluate the SQL statement. With queries, the values are also used to identify the active set.

In our example, OPEN associates EMPCURSOR with BNDDSC as follows:

     EXEC SQL 
         OPEN EMPCUR USING DESCRIPTOR BNDDSC 
     END-EXEC. 

Remember, BNDDSC must not be prefixed with a colon.

Then, OPEN executes the SQL statement. With queries, OPEN also identifies the active set and positions the cursor at the first row.

DESCRIBE the Select List

If the dynamic SQL statement is a query, the DESCRIBE SELECT LIST statement must follow the OPEN statement but precede the FETCH statement.

DESCRIBE SELECT LIST puts descriptions of select-list items into a select descriptor. In our example, DESCRIBE readies SELDSC as follows:

     EXEC SQL 
         DESCRIBE SELECT LIST FOR SQLSTMT INTO SELDSC 
     END-EXEC. 

Accessing the data dictionary, DESCRIBE sets the length and datatype of each select-list value.

Figure 11-7 shows the select descriptor in our example after the DESCRIBE. Notice that DESCRIBE has set SQLDFND to the actual number of items found in the query select list. If the SQL statement is not a query, SQLDFND is set to zero. Also notice that the NUMBER lengths are not usable yet. For columns defined as NUMBER, you must use the library subroutine SQLPRC to extract precision and scale. See the section "Coercing Datatypes".

Figure 11-7 Select Descriptor after the DESCR

Select after DESCR

Reset Number of Select-List Items

Next, you must reset the maximum number of select-list items to the number actually found by DESCRIBE, as follows:

     MOVE SQLDFND IN SELDSC TO SQLDNUM IN SELDSC. 

Reset Length/Datatype of Each Select-List Item

Before fetching the select-list values, the example resets some elements in the length and datatype tables for display purposes.

 PROCEDURE DIVISION. 
     ... 
     PERFORM COERCE-COLUMN-TYPE 
         VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC. 
     ... 
 COERCE-COLUMN-TYPE. 
*    Clear NULL bit. 
     CALL "SQLNUL" USING SELDVTYP(J), SELDVTYP(J), NULL-STATUS. 

*    If datatype is DATE, lengthen to 9 characters. 
     IF SELDVTYP(J) = 12 
         MOVE 9 TO SELDVLN(J). 

*    If datatype is NUMBER, extract precision and scale. 
     MOVE 0 TO DISPLAY-LENGTH. 
     IF SELDVTYP(J) = 2 AND PRECISION = 0 
         MOVE 10 TO DISPLAY-LENGTH. 
     IF SELDVTYP(J) = 2 AND PRECISION > 0 
         ADD 2 TO PRECISION 
         MOVE PRECISION TO DISPLAY-LENGTH. 
     IF SELDVTYP(J) = 2 
         IF DISPLAY-LENGTH > MAX-LENGTH 
             DISPLAY "Column value too large for data buffer." 
             GO TO END-PROGRAM 
         ELSE 
             MOVE DISPLAY-LENGTH TO SELDVLN(J). 

*    Coerce datatypes to VARCHAR2. 
     MOVE 1 TO SELDVTYP(J). 

Figure 11-8 shows the resulting select descriptor. Notice that the NUMBER lengths are now usable and that all the datatypes are VARCHAR2. The lengths in SELDVLN(2) and SELDVLN(3) are 6 and 9 because we increased the DESCRIBEd lengths of 4 and 7 by 2 to allow for a possible sign and decimal point.

Figure 11-8 Select Descriptor before the FETCH

Select after DESCR

FETCH Rows from the Active Set

FETCH returns a row from the active set, stores select-list values in the data buffers, and advances the cursor to the next row in the active set. If there are no more rows, FETCH sets SQLCODE in the SQLCA, the SQLCODE variable, or the SQLSTATE variable to the "no data found" error code. In the following example, FETCH returns the values of columns ENAME, EMPNO, and COMM to SELDSC:

     EXEC SQL 
         FETCH EMPCURSOR USING DESCRIPTOR SELDSC 
     END-EXEC. 

Figure 11-9 shows the select descriptor in our example after the FETCH. Notice that Oracle has stored the select-list and indicator values in the data buffers addressed by the elements of SELDV and SELDI.

For output buffers of datatype 1, Oracle, using the lengths stored in SELDVLN, left-justifies CHAR or VARCHAR2 data, and right-justifies NUMBER data.

The value MARTIN was retrieved from a VARCHAR2(10) column in the EMP table. Using the length in SELDVLN(1), Oracle left-justifies the value in a 10-byte field, filling the buffer.

The value 7654 was retrieved from a NUMBER(4) column and coerced to 7654. However, the length in SELDVLN(2) was increased by two to allow for a possible sign and decimal point, so Oracle right-justifies the value in a 6-byte field.

The value 482.50 was retrieved from a NUMBER(7,2) column and coerced to 482.50. Again, the length in SELDVLN(3) was increased by two, so Oracle right-justifies the value in a 9-byte field.

Get and Process Select-List Values

After the FETCH, your program can process the select-list values returned by FETCH. In our example, values for columns ENAME, EMPNO, and COMM are processed.

CLOSE the Cursor

CLOSE disables the cursor. In our example, CLOSE disables EMPCURSOR as follows:

     EXEC SQL CLOSE EMPCURSOR END-EXEC

Figure 11-9 Select Descriptor after the FETCH

Select r after FETCH

Using Host Tables with Method 4

To use input or output host tables with Method 4, you must use the optional FOR clause to tell Oracle the size of your host table. For more information about the FOR clause, see Chapter 7, "Host Tables".

Set descriptor entries for the Jth select-list item or bind variable, but instead of addressing a single data buffer, SELDVLN(J) or BNDDVLN(J) addresses a table of data buffers. Then use a FOR clause in the EXECUTE or FETCH statement, as appropriate, to tell Oracle the number of table elements you want to process.

This procedure is necessary because Oracle has no other way of knowing the size of your host table.

In the following example, two input host tables are used to insert 8 pairs of values of EMPNO and DEPTNO into the table EMP. Note that EXECUTE can be used for non-queries with Method 4.

 IDENTIFICATION DIVISION. 
 PROGRAM-ID. DYN4INS. 
 ENVIRONMENT DIVISION. 
 DATA DIVISION. 
 WORKING-STORAGE SECTION. 
 01  BNDDSC. 
     02  SQLDNUM              PIC S9(9) COMP VALUE 2. 
     02  SQLDFND              PIC S9(9) COMP. 
     02  BNDDVAR              OCCURS 2 TIMES. 
         03 BNDDV             PIC S9(9) COMP. 
         03 BNDDFMT           PIC S9(9) COMP. 
         03 BNDDVLN           PIC S9(9) COMP. 
         03 BNDDFMTL          PIC S9(4) COMP. 
         03 BNDDVTYP          PIC S9(4) COMP. 
         03 BNDDI             PIC S9(9) COMP. 
         03 BNDDH-VNAME       PIC S9(9) COMP. 
         03 BNDDH-MAX-VNAMEL  PIC S9(4) COMP. 
         03 BNDDH-CUR-VNAMEL  PIC S9(4) COMP. 
         03 BNDDI-VNAME       PIC S9(9) COMP. 
         03 BNDDI-MAX-VNAMEL  PIC S9(4) COMP. 
         03 BNDDI-CUR-VNAMEL  PIC S9(4) COMP. 
         03 BNDDFCLP          PIC S9(9) COMP. 
         03 BNDDFCRCP         PIC S9(9) COMP. 
 01  XBNDDI. 
     03  BND-DI               OCCURS 2 TIMES PIC S9(4) COMP. 
 01  XBNDDIVNAME. 
     03  BND-DI-VNAME         OCCURS 2 TIMES PIC X(80). 
 01  XBNDDV. 
*    Since you know what the SQL statement will be, you can set 
*    up a two-dimensional table with a maximum of 2 columns and 
*    8 rows.  Each element can be up to 10 characters long.  (You 
*    can alter these values according to your needs.) 
     03  BND-COLUMN           OCCURS 2 TIMES. 
         05  BND-ELEMENT      OCCURS 8 TIMES PIC X(10). 
 01  XBNDDHVNAME. 
     03  BND-DH-VNAME         OCCURS 2 TIMES PIC X(80).  
 01  COLUMN-INDEX             PIC 999. 
 01  ROW-INDEX                PIC 999. 
 01  DUMMY-INTEGER            PIC 9999.
     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
         01  USERNAME         PIC X(20). 
         01  PASSWD           PIC X(20). 
         01  DYN-STATEMENT    PIC X(80). 
         01  NUMBER-OF-ROWS   PIC S9(4) COMP. 
     EXEC SQL END DECLARE SECTION END-EXEC. 

     EXEC SQL INCLUDE SQLCA END-EXEC. 

 PROCEDURE DIVISION. 
 START-MAIN. 

     EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC. 

     MOVE "SCOTT" TO USERNAME. 
     MOVE "TIGER" TO PASSWD. 
     EXEC SQL 
         CONNECT :USERNAME IDENTIFIED BY :PASSWD 
     END-EXEC. 
     DISPLAY "Connected to Oracle". 

*    Initialize bind and select descriptors. 
     PERFORM INIT-BNDDSC THRU INIT-BNDDSC-EXIT 
         VARYING COLUMN-INDEX FROM 1 BY 1 
         UNTIL COLUMN-INDEX > 2. 

*    Set up the SQL statement. 
     MOVE SPACES TO DYN-STATEMENT. 
     MOVE "INSERT INTO EMP(EMPNO, DEPTNO) VALUES(:EMPNO,:DEPTNO)" 
         TO DYN-STATEMENT.
     DISPLAY DYN-STATEMENT.

*    Prepare the SQL statement. 
     EXEC SQL 
         PREPARE S1 FROM :DYN-STATEMENT 
     END-EXEC. 

*    Describe the bind variables. 
     EXEC SQL 
         DESCRIBE BIND VARIABLES FOR S1 INTO BNDDSC 
     END-EXEC. 

     PERFORM Z-BIND-TYPE THRU Z-BIND-TYPE-EXIT 
         VARYING COLUMN-INDEX FROM 1 BY 1 
         UNTIL COLUMN-INDEX > 2. 

     IF SQLDFND IN BNDDSC < 0 
         DISPLAY "TOO MANY BIND VARIABLES." 
         GO TO SQL-ERROR 
     ELSE 
         DISPLAY "BIND VARS = " WITH NO ADVANCING 
         MOVE SQLDFND IN BNDDSC TO DUMMY-INTEGER 
         DISPLAY DUMMY-INTEGER 
         MOVE SQLDFND IN BNDDSC TO SQLDNUM IN BNDDSC. 

         MOVE 8 TO NUMBER-OF-ROWS. 
         PERFORM GET-ALL-VALUES THRU GET-ALL-VALUES-EXIT 
             VARYING ROW-INDEX FROM 1 BY 1 
             UNTIL ROW-INDEX > NUMBER-OF-ROWS. 

*    Execute the SQL statement. 
     EXEC SQL FOR :NUMBER-OF-ROWS 
         EXECUTE S1 USING DESCRIPTOR BNDDSC 
     END-EXEC. 

     DISPLAY "INSERTED " WITH NO ADVANCING. 
     MOVE SQLERRD(3) TO DUMMY-INTEGER. 
     DISPLAY DUMMY-INTEGER WITH NO ADVANCING. 
     DISPLAY " ROWS.". 
     GO TO END-SQL. 

 SQL-ERROR. 
*    Display any SQL error message and code. 
     DISPLAY SQLERRMC. 
     EXEC SQL ROLLBACK WORK RELEASE END-EXEC. 
     STOP RUN. 

 END-SQL. 
     EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. 
     EXEC SQL COMMIT WORK RELEASE END-EXEC. 
     STOP RUN. 

 INIT-BNDDSC. 
*    Start of COBOL PERFORM procedures, initialize the bind 
*    descriptor. 
     MOVE 80 TO BNDDH-MAX-VNAMEL(COLUMN-INDEX). 
     CALL "SQLADR" USING 
         BND-DH-VNAME(COLUMN-INDEX) 
         BNDDH-VNAME(COLUMN-INDEX). 
     MOVE 80 TO BNDDI-MAX-VNAMEL(COLUMN-INDEX). 
     CALL "SQLADR" USING 
         BND-DI-VNAME(COLUMN-INDEX) 
         BNDDI-VNAME (COLUMN-INDEX). 
     MOVE 10 TO BNDDVLN(COLUMN-INDEX). 
     CALL "SQLADR" USING 
         BND-ELEMENT(COLUMN-INDEX,1) 
         BNDDV(COLUMN-INDEX). 
     MOVE ZERO TO BNDDI(COLUMN-INDEX). 
     CALL "SQLADR" USING 
         BND-DI(COLUMN-INDEX) 
         BNDDI(COLUMN-INDEX). 
     MOVE ZERO TO BNDDFMT(COLUMN-INDEX). 
     MOVE ZERO TO BNDDFMTL(COLUMN-INDEX). 
     MOVE ZERO TO BNDDFCLP(COLUMN-INDEX). 
     MOVE ZERO TO BNDDFCRCP(COLUMN-INDEX). 
 INIT-BNDDSC-EXIT. 
     EXIT.

 Z-BIND-TYPE. 
*    Replace the 0s DESCRIBEd into the datatype table with 1s to 
*    avoid an "invalid datatype" Oracle error. 
     MOVE 1 TO BNDDVTYP(COLUMN-INDEX). 

 Z-BIND-TYPE-EXIT. 
     EXIT. 

 GET-ALL-VALUES. 
*    Get the bind variables for each row. 
     DISPLAY "ENTER VALUES FOR ROW NUMBER ",ROW-INDEX. 
     PERFORM GET-BIND-VARS 
         VARYING COLUMN-INDEX FROM 1 BY 1 
         UNTIL COLUMN-INDEX > SQLDFND IN BNDDSC. 
 GET-ALL-VALUES-EXIT. 
     EXIT. 

 GET-BIND-VARS. 
*    Get the value of each bind variable. 
     DISPLAY "    ENTER VALUE FOR ",BND-DH-VNAME(COLUMN-INDEX) 
         WITH NO ADVANCING. 
     ACCEPT BND-ELEMENT(COLUMN-INDEX,ROW-INDEX). 
 GET-BIND-VARS-EXIT. 
     EXIT.  

Sample Program 10: Dynamic SQL Method 4

This program shows the basic steps required to use dynamic SQL Method 4. After logging on, the program prompts the user for a SQL statement, prepares statement, declares a cursor, checks for any bind variables using DESCRIBE BIND, opens the cursor, and describes any select-list variables. If the input SQL statement is a query, the program fetches each row of data, then closes the cursor.

      ***************************************************************
      * Sample Program 10: Dynamic SQL Method 4                     *
      *                                                             *
      * This program shows the basic steps required to use dynamic  *
      * SQL Method 4.  After logging on to ORACLE, the program      *
      * prompts the user for a SQL statement, PREPAREs the          *
      * statement, DECLAREs a cursor, checks for any bind variables *
      * using DESCRIBE BIND, OPENs the cursor, and DESCRIBEs any    *
      * select-list variables.  If the input SQL statement is a     *
      * query, the program FETCHes each row of data, then CLOSEs    *
      * the cursor.                                                 *
      ***************************************************************

       IDENTIFICATION DIVISION.
       PROGRAM-ID.  DYNSQL4.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  BNDDSC.

           02  SQLDNUM               PIC S9(9) COMP VALUE 20.
           02  SQLDFND               PIC S9(9) COMP.
           02  BNDDVAR               OCCURS 20 TIMES.
               03  BNDDV             PIC S9(9) COMP.
               03  BNDDFMT           PIC S9(9) COMP.
               03  BNDDVLN           PIC S9(9) COMP.
               03  BNDDFMTL          PIC S9(4) COMP.
               03  BNDDVTYP          PIC S9(4) COMP.
               03  BNDDI             PIC S9(9) COMP.
               03  BNDDH-VNAME       PIC S9(9) COMP.
               03  BNDDH-MAX-VNAMEL  PIC S9(4) COMP.
               03  BNDDH-CUR-VNAMEL  PIC S9(4) COMP.
               03  BNDDI-VNAME       PIC S9(9) COMP.
               03  BNDDI-MAX-VNAMEL  PIC S9(4) COMP.
               03  BNDDI-CUR-VNAMEL  PIC S9(4) COMP.
               03  BNDDFCLP          PIC S9(9) COMP.
               03  BNDDFCRCP         PIC S9(9) COMP.

       01  XBNDDI.

           03  BND-DI                OCCURS 20 TIMES PIC S9(4) COMP.

       01  XBNDDIVNAME.
           03  BND-DI-VNAME          OCCURS 20 TIMES PIC X(80).
       01  XBNDDV.
           03  BND-DV                OCCURS 20 TIMES PIC X(80).
       01  XBNDDHVNAME.
           03  BND-DH-VNAME          OCCURS 20 TIMES PIC X(80).

       01  SELDSC.

           02  SQLDNUM               PIC S9(9) COMP VALUE 20.
           02  SQLDFND               PIC S9(9) COMP.
           02  SELDVAR               OCCURS 20 TIMES.
               03  SELDV             PIC S9(9) COMP.
               03  SELDFMT           PIC S9(9) COMP.
               03  SELDVLN           PIC S9(9) COMP.
               03  SELDFMTL          PIC S9(4) COMP.
               03  SELDVTYP          PIC S9(4) COMP.
               03  SELDI             PIC S9(9) COMP.
               03  SELDH-VNAME       PIC S9(9) COMP.
               03  SELDH-MAX-VNAMEL  PIC S9(4) COMP.
               03  SELDH-CUR-VNAMEL  PIC S9(4) COMP.
               03  SELDI-VNAME       PIC S9(9) COMP.
               03  SELDI-MAX-VNAMEL  PIC S9(4) COMP.
               03  SELDI-CUR-VNAMEL  PIC S9(4) COMP.
               03  SELDFCLP          PIC S9(9) COMP.
               03  SELDFCRCP         PIC S9(9) COMP.

       01  XSELDI.

           03  SEL-DI                OCCURS 20 TIMES PIC S9(4) COMP.

       01  XSELDIVNAME.
           03  SEL-DI-VNAME          OCCURS 20 TIMES PIC X(80).
       01  XSELDV.
           03  SEL-DV                OCCURS 20 TIMES PIC X(80).
       01  XSELDHVNAME.
           03  SEL-DH-VNAME          OCCURS 20 TIMES PIC X(80).

       01  TABLE-INDEX               PIC 9(3).
       01  VAR-COUNT                 PIC 9(2).
       01  ROW-COUNT                 PIC 9(4).
       01  NO-MORE-DATA              PIC X(1) VALUE "N".
       01  NULLS-ALLOWED             PIC S9(9) COMP.

       01  PRECISION                 PIC S9(9) COMP.
       01  SCALE                     PIC S9(9) COMP.

       01  DISPLAY-LENGTH            PIC S9(9) COMP.
       01  MAX-LENGTH                PIC S9(9) COMP VALUE 80.
       01  COLUMN-NAME               PIC X(30).
       01  NULL-VAL                  PIC X(80) VALUE SPACES.
           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME       PIC X(20).
       01  PASSWD         PIC X(20).
       01  DYN-STATEMENT  PIC X(80).
           EXEC SQL END DECLARE SECTION   END-EXEC.
           EXEC SQL INCLUDE SQLCA         END-EXEC.

       PROCEDURE DIVISION.
       START-MAIN.

           EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.

           DISPLAY "USERNAME: " WITH NO ADVANCING.

           ACCEPT USERNAME.

           DISPLAY "PASSWORD: " WITH NO ADVANCING.

           ACCEPT PASSWD.

           EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD END-EXEC.
           DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME.

      *    INITIALIZE THE BIND AND SELECT DESCRIPTORS.

           PERFORM INIT-BNDDSC
               VARYING TABLE-INDEX FROM 1 BY 1 
               UNTIL TABLE-INDEX > 20.

           PERFORM INIT-SELDSC
               VARYING TABLE-INDEX FROM 1 BY 1 
               UNTIL TABLE-INDEX > 20.

      *    GET A SQL STATEMENT FROM THE OPERATOR.

           DISPLAY "ENTER SQL STATEMENT WITHOUT TERMINATOR:".
           DISPLAY ">" WITH NO ADVANCING.

           ACCEPT DYN-STATEMENT.

           DISPLAY " ".

      *    PREPARE THE SQL STATEMENT AND DECLARE A CURSOR.

           EXEC SQL  PREPARE S1 FROM :DYN-STATEMENT  END-EXEC.
           EXEC SQL  DECLARE C1 CURSOR FOR S1        END-EXEC.

      *    DESCRIBE ANY BIND VARIABLES.

           EXEC SQL  DESCRIBE BIND VARIABLES FOR S1 INTO BNDDSC
           END-EXEC.

           IF SQLDFND IN BNDDSC < 0
               DISPLAY "TOO MANY BIND VARIABLES."
               GO TO END-SQL
           ELSE
               DISPLAY "NUMBER OF BIND VARIABLES: " WITH NO ADVANCING
               MOVE SQLDFND IN BNDDSC TO VAR-COUNT
               DISPLAY VAR-COUNT
               MOVE SQLDFND IN BNDDSC TO SQLDNUM IN BNDDSC
           END-IF.

      *    REPLACE THE 0S DESCRIBED INTO THE DATATYPE FIELDS OF THE
      *    BIND DESCRIPTOR WITH 1S TO AVOID AN "INVALID DATATYPE"
      *    ORACLE ERROR

           MOVE 1 TO TABLE-INDEX.
       FIX-BIND-TYPE.
               MOVE 1 TO BNDDVTYP(TABLE-INDEX)
               ADD 1 TO TABLE-INDEX
               IF TABLE-INDEX <= 20
                   GO TO FIX-BIND-TYPE.

      *    LET THE USER FILL IN THE BIND VARIABLES.

           IF SQLDFND IN BNDDSC = 0
               GO TO DESCRIBE-ITEMS.
           MOVE 1 TO TABLE-INDEX.
       GET-BIND-VAR.
               DISPLAY "ENTER VALUE FOR ", BND-DH-VNAME(TABLE-INDEX).

               ACCEPT BND-DV(TABLE-INDEX).

               ADD 1 TO TABLE-INDEX
               IF TABLE-INDEX <= SQLDFND IN BNDDSC
                   GO TO GET-BIND-VAR.

      *    OPEN THE CURSOR AND DESCRIBE THE SELECT-LIST ITEMS.

       DESCRIBE-ITEMS.

           EXEC SQL  OPEN C1 USING DESCRIPTOR BNDDSC          END-EXEC.
           EXEC SQL  DESCRIBE SELECT LIST FOR S1 INTO SELDSC  END-EXEC.

           IF SQLDFND IN SELDSC < 0
               DISPLAY "TOO MANY SELECT-LIST ITEMS."
               GO TO END-SQL
           ELSE
               DISPLAY "NUMBER OF SELECT-LIST ITEMS: "
                   WITH NO ADVANCING
               MOVE SQLDFND IN SELDSC TO VAR-COUNT
               DISPLAY VAR-COUNT
               DISPLAY " "
               MOVE SQLDFND IN SELDSC TO SQLDNUM IN SELDSC
           END-IF.

      *    COERCE THE DATATYPE OF ALL SELECT-LIST ITEMS TO VARCHAR2.

           IF SQLDNUM IN SELDSC > 0
               PERFORM COERCE-COLUMN-TYPE
                   VARYING TABLE-INDEX FROM 1 BY 1
                   UNTIL TABLE-INDEX > SQLDNUM IN SELDSC
               DISPLAY " ".

      *    FETCH EACH ROW AND PRINT EACH SELECT-LIST VALUE.

           IF SQLDNUM IN SELDSC > 0
               PERFORM FETCH-ROWS UNTIL NO-MORE-DATA = "Y".

           DISPLAY " "
           DISPLAY "NUMBER OF ROWS PROCESSED: " WITH NO ADVANCING.
           MOVE SQLERRD(3) TO ROW-COUNT.
           DISPLAY ROW-COUNT.

      *    CLEAN UP AND TERMINATE.

           EXEC SQL  CLOSE C1             END-EXEC.
           EXEC SQL  COMMIT WORK RELEASE  END-EXEC.
           DISPLAY " ".
           DISPLAY "HAVE A GOOD DAY!".
           DISPLAY " ".
           STOP RUN.

      *    DISPLAY ORACLE ERROR MESSAGE AND CODE.

       SQL-ERROR.
           DISPLAY " ".
           DISPLAY SQLERRMC.
       END-SQL.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
           EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
           STOP RUN.

      *    PERFORMED SUBROUTINES BEGIN HERE:

      *    INIT-BNDDSC: INITIALIZE THE BIND DESCRIPTOR.

       INIT-BNDDSC.

           MOVE SPACES TO BND-DH-VNAME(TABLE-INDEX).
           MOVE 80 TO BNDDH-MAX-VNAMEL(TABLE-INDEX).
           CALL "SQLADR" USING 
               BND-DH-VNAME(TABLE-INDEX) 
               BNDDH-VNAME(TABLE-INDEX). 
        
           MOVE SPACES TO BND-DI-VNAME(TABLE-INDEX).
           MOVE 80 TO BNDDI-MAX-VNAMEL(TABLE-INDEX).
           CALL "SQLADR" USING 
               BND-DI-VNAME(TABLE-INDEX) 
               BNDDI-VNAME (TABLE-INDEX).
        
           MOVE SPACES TO BND-DV(TABLE-INDEX).
           MOVE 80 TO BNDDVLN(TABLE-INDEX).
           CALL "SQLADR" USING 
               BND-DV(TABLE-INDEX) 
               BNDDV(TABLE-INDEX).
           MOVE ZERO TO BND-DI(TABLE-INDEX).
           CALL "SQLADR" USING 
               BND-DI(TABLE-INDEX) 
               BNDDI(TABLE-INDEX).

           MOVE ZERO TO BNDDFMT(TABLE-INDEX).
           MOVE ZERO TO BNDDFMTL(TABLE-INDEX).
           MOVE ZERO TO BNDDFCLP(TABLE-INDEX).
           MOVE ZERO TO BNDDFCRCP(TABLE-INDEX).

      *    INIT-SELDSC: INITIALIZE THE SELECT DESCRIPTOR.

       INIT-SELDSC.

           MOVE SPACES TO SEL-DH-VNAME(TABLE-INDEX).
           MOVE 80 TO SELDH-MAX-VNAMEL(TABLE-INDEX).
           CALL "SQLADR" USING 
               SEL-DH-VNAME(TABLE-INDEX) 
               SELDH-VNAME(TABLE-INDEX). 
        
           MOVE SPACES TO SEL-DI-VNAME(TABLE-INDEX).
           MOVE 80 TO SELDI-MAX-VNAMEL(TABLE-INDEX).
           CALL "SQLADR" USING 
               SEL-DI-VNAME(TABLE-INDEX) 
               SELDI-VNAME (TABLE-INDEX).

           MOVE SPACES TO SEL-DV(TABLE-INDEX).
           MOVE 80 TO SELDVLN(TABLE-INDEX).
           CALL "SQLADR" USING 
               SEL-DV(TABLE-INDEX) 
               SELDV(TABLE-INDEX).

           MOVE ZERO TO SEL-DI(TABLE-INDEX).
           CALL "SQLADR" USING 
               SEL-DI(TABLE-INDEX) 
               SELDI(TABLE-INDEX).

           MOVE ZERO TO SELDFMT(TABLE-INDEX).
           MOVE ZERO TO SELDFMTL(TABLE-INDEX).
           MOVE ZERO TO SELDFCLP(TABLE-INDEX).
           MOVE ZERO TO SELDFCRCP(TABLE-INDEX).

      *    COERCE SELECT-LIST DATATYPES TO VARCHAR2.

       COERCE-COLUMN-TYPE.
           CALL "SQLNUL" USING
               SELDVTYP(TABLE-INDEX)
               SELDVTYP(TABLE-INDEX)
               NULLS-ALLOWED.

      *    IF DATATYPE IS DATE, LENGTHEN TO 9 CHARACTERS.
           IF SELDVTYP(TABLEK-INDEX) = 12
               MOVE 9 TO SELDVLN(TABLE-INDEX).

      *    IF DATATYPE IS NUMBER, SET LENGTH TO PRECISION.
           IF SELDVTYP(TABLE-INDEX) = 2
               CALL "SQLPRC" USING
                   SELDVLN(TABLE-INDEX)
                   PRECISION
                   SCALE.
           MOVE 0 TO DISPLAY-LENGTH.
           IF SELDVTYP(TABLE-INDEX) = 2 AND PRECISION = 0
               MOVE 40 TO DISPLAY-LENGTH.
           IF SELDVTYP(TABLE-INDEX) = 2 AND PRECISION > 0
               ADD 2 TO PRECISION
               MOVE PRECISION TO DISPLAY-LENGTH.

           IF SELDVTYP(TABLE-INDEX) = 2
               IF DISPLAY-LENGTH > MAX-LENGTH
                   DISPLAY "COLUMN VALUE TOO LARGE FOR DATA BUFFER."
                   GO TO END-SQL
               ELSE
                   MOVE DISPLAY-LENGTH TO SELDVLN(TABLE-INDEX).

      *    COERCE DATATYPES TO VARCHAR2.
           MOVE 1 TO SELDVTYP(TABLE-INDEX).

      *    DISPLAY COLUMN HEADING.
           MOVE SEL-DH-VNAME(TABLE-INDEX) TO COLUMN-NAME.
           DISPLAY COLUMN-NAME(1:SELDVLN(TABLE-INDEX)), " "
               WITH NO ADVANCING.

      *FETCH A ROW AND PRINT THE SELECT-LIST VALUE.

       FETCH-ROWS.
           EXEC SQL  FETCH C1 USING DESCRIPTOR SELDSC  END-EXEC.
           IF SQLCODE NOT = 0
               MOVE "Y" TO NO-MORE-DATA.
           IF SQLCODE = 0
               PERFORM PRINT-COLUMN-VALUES
                   VARYING TABLE-INDEX FROM 1 BY 1
                   UNTIL TABLE-INDEX > SQLDNUM IN SELDSC
               DISPLAY " ".

      *PRINT A SELECT-LIST VALUE.

       PRINT-COLUMN-VALUES.
           IF SEL-DI(TABLE-INDEX) = -1
             DISPLAY NULL-VAL(1:SELDVLN(TABLE-INDEX)), " "
                 WITH NO ADVANCING
           ELSE
             DISPLAY SEL-DV(TABLE-INDEX)(1:SELDVLN(TABLE-INDEX)), " "
                 WITH NO ADVANCING
           END-IF.
PKɕȇPKFJOEBPS/pco12thr.htm Multithreaded Applications

12 Multithreaded Applications

If your development platform does not support threads, you can ignore this chapter.

The sections of this chapter are:

Introduction to Threads

Multithreaded applications have multiple threads executing in a shared address space. Threads are "lightweight" subprocesses that execute within a process. They share code and data segments, but have their own program counters, machine registers, and stack. Variables declared without the thread-local attribute in working storage (as opposed to local-storage or thread-local storage) are common to all threads, and a mutual exclusivity mechanism is often required to manage access to these variables from multiple threads within an application. Mutexes are the synchronization mechanism to insure that data integrity is preserved.

For further discussion of mutexes, see texts on multithreading. For more detailed information about multithreaded applications, see the documentation of your threads functions.

Pro*COBOL supports development of multithreaded Oracle Server applications (on platforms that support multithreaded applications) using the following:


Note:

While your platform may support a particular thread package, see your platform-specific Oracle documentation to determine whether Oracle supports it.

The chapter's topics discuss how to use the preceding features to develop multithreaded Pro*COBOL applications:

Runtime Contexts in Pro*COBOL

To loosely couple a thread and a connection, in Pro*COBOL we introduce the concept of a runtime context. The runtime context includes the following resources and their current states:

Rather than simply supporting a loose coupling between threads and connections, Pro*COBOL enables you to loosely couple threads with runtime contexts. Pro*COBOL enables your application to define a handle to a runtime context, and pass that handle from one thread to another.

For example, an interactive application spawns a thread, T1, to execute a query and return the first 10 rows to the application. T1 then terminates. After obtaining the necessary user input, another thread, T2, is spawned (or an existing thread is used) and the runtime context for T1 is passed to T2 so it can fetch the next 10 rows by processing the same cursor.This is shown in Figure 12-1:

Figure 12-1 Loosely Coupling Connections and Threads

Loose Coupling

Runtime Context Usage Models

Two possible models for using runtime contexts in multithreaded applications are shown here:

Regardless of the model you use for runtime contexts, you cannot share a runtime context between multiple threads at the same time. If two or more threads attempt to use the same runtime context simultaneously, a runtime error occurs

Multiple Threads Sharing a Single Runtime Context

Figure 12-2 shows an application running in a multithreaded environment. The various threads share a single runtime context to process one or more SQL statements. Again, runtime contexts cannot be shared by multiple threads at the same time. The mutexes in Figure 12-2 show how to prevent concurrent usage.

Figure 12-2 Context Sharing Among Threads

Context Sharing

Multiple Threads Sharing Multiple Runtime Contexts

Figure 12-3 shows an application that executes multiple threads using multiple runtime contexts. In this situation, the application does not require mutexes, because each thread has a dedicated runtime context.

Figure 12-3 No Context Sharing Among Threads

No Context Sharing

User Interface Features for Multithreaded Applications

Pro*COBOL provides the following user-interface features to support multithreaded applications:

THREADS Option

With THREADS=YES specified on the command line, Pro*COBOL ensures that the generated code is thread-safe, given that you follow the guidelines described in "Multithreading Programming Considerations". With THREADS=YES specified, Pro*COBOL verifies that all SQL statements execute within the scope of a user-defined runtime context. If your program does not meet this requirement, a precompiler error is returned.

Embedded SQL Statements and Directives for Runtime Contexts

The following embedded SQL statements and directives support the definition and usage of runtime contexts and threads:

  • EXEC SQL ENABLE THREADS END-EXEC.

  • EXEC SQL CONTEXT ALLOCATE :context_var END-EXEC.

  • EXEC SQL CONTEXT USE { :context_var | DEFAULT} END-EXEC.

  • EXEC SQL CONTEXT FREE :context_var END-EXEC.

For these EXEC SQL statements, context_var is the handle to the runtime context and must be declared of type SQL-CONTEXT as follows:

 01  SQL-CONTEXT context_var END-EXEC.

Using DEFAULT means that the default (global) runtime context will be used in all embedded SQL statements that lexically follow until another CONTEXT USE statement overrides it.

Examples illustrating the various uses of context statements are shown.

Host Tables of SQL-CONTEXT Are Not Allowed

You cannot declare host tables of SQL-CONTEXT. Instead, declare a host table of S9(9) COMP variables and then pass them to the subprogram one at a time after redeclaring them in the subprogram as SQL-CONTEXT.

EXEC SQL ENABLE THREADS

This executable SQL statement initializes a process that supports multiple threads. This must be the first executable SQL statement in a program that contains a multithreaded application. There can only be one ENABLE THREADS statement in all files of an application, or an error results. For more detailed information, see "ENABLE THREADS (Executable Embedded SQL Extension)".

EXEC SQL CONTEXT ALLOCATE

This executable SQL statement allocates and initializes memory for the specified runtime context; the runtime-context variable must be declared of type SQL_CONTEXT. For more detailed information, see "CONTEXT ALLOCATE (Executable Embedded SQL Extension)".

EXEC SQL CONTEXT USE

The EXEC SQL CONTEXT USE directive instructs the precompiler to use the specified runtime context for subsequent executable SQL statements. The runtime context specified must be previously allocated using an EXEC SQL CONTEXT ALLOCATE statement.

The EXEC SQL CONTEXT USE directive works similarly to the EXEC SQL WHENEVER directive in that it affects all executable SQL statements which positionally follow it in a given source file without regard to standard COBOL scope rules.

For more detailed information, see "CONTEXT USE (Oracle Embedded SQL Directive)", and "CONTEXT ALLOCATE (Executable Embedded SQL Extension)".

EXEC SQL CONTEXT FREE

The EXEC SQL CONTEXT FREE executable SQL statement frees the memory associated with the specified runtime context and places a null pointer in the host program variable. For more detailed information, see "CONTEXT FREE (Executable Embedded SQL Extension)".

Communication with Pro*C/C++ Programs

Runtime contexts can be passed using arguments defined in the Linkage Section. Multithreaded Pro*C/C++ programs can call Pro*COBOL subprograms and Pro*COBOL programs can call subprograms written in Pro*C/C++.

Multithreading Programming Considerations

While Oracle ensures that the SQLLIB code is thread-safe, you are responsible for ensuring that your source code is designed to work properly with threads. For example, carefully consider the scope of the variables you use.

In addition, multithreading requires design decisions regarding the following:

  • Including one SQLCA for each runtime context.

  • Declaring the SQLDA as a thread-safe group item, like the SQLCA, typically an auto variable, one for each runtime context.

  • Declaring host variables in a thread-safe fashion, in other words, carefully consider your use of static and global host variables.

  • Avoiding simultaneous use of a runtime context in multiple threads.

  • Whether or not to use default database connections or to explicitly define them using the AT clause.

No more than one executable embedded SQL statement, for example, EXEC SQL UPDATE, may be outstanding on a runtime context at a given time.

Existing requirements for precompiled applications also apply. For example, all references to a given cursor must appear in the same source file.

Restrictions on Multithreading

The following restrictions be in effect when using threads:

  • You cannot use an array of datatype SQL-CONTEXT.

  • Concurrent threads should each have its own SQLCA.

  • Concurrent threads should each have its own context areas.

Multiple Context Examples

The code fragments in this section show how to use multiple contexts, and demonstrate the scope of the context use statement.

Example 1

In the first example, the precompiler option setting THREADS=YES is not needed, because we are not generating threads:

 IDENTIFICATION DIVISION.
 PROGRAM-ID. MAIN.
 ...
* declare a context area
 01  CTX1  SQL-CONTEXT.
 01  UID1  PIC X(11) VALUE "SCOTT/TIGER".
 01  UID2  PIC X(10) VALUE "MARY/LION"

 PROCEDURE DIVISION.
...
* allocate context area
     EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
     EXEC SQL CONTEXT USE :CTX1 END-EXEC.
* all statements until the next context use will use CTX1
     EXEC SQL CONNECT :UID1 END-EXEC.
     EXEC SQL SELECT ....
     EXEC SQL CONTEXT USE DEFAULT END-EXEC.
* all statements physically after the preceding lines will use the default context
     EXEC SQL CONNECT :UID2 END-EXEC.
     EXEC SQL INSERT ...
 ...

Example 2

This next example shows multiple contexts. One context is used by the generated thread while the other is used by the main program. The started thread, SUBPRGM1, will use context CTX1, which is passed to it through the LINKAGE SECTION. This example also demonstrates the scope of the CONTEXT USE statement.


Note:

You must precompile the main program file, and the main program of every subsequent example in this section, with the option THREADS=YES.

 IDENTIFICATION DIVISION.
 PROGRAM-ID. MAIN.
 ...
* declare two context areas
 01  CTX1  SQL-CONTEXT.
 01  CTX2  SQL-CONTEXT.

 PROCEDURE DIVISION.

* enable threading
     EXEC SQL ENABLE THREADS END-EXEC.

* allocate context areas
     EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
     EXEC SQL CONTEXT ALLOCATE :CTX2 END-EXEC.

* include your code to start thread "SUBPGM1" using CTX1 here.

     EXEC SQL CONTEXT USE :CTX2 END-EXEC.
* all statement physically after the preceding lines will use CTX2

     EXEC SQL CONNECT :USERID END-EXEC.
     EXEC SQL INSERT .....
 ...

The thread SUBPRGM1 is in a another file:

 PROGRAM-ID. SUBPRGM1.
 ...
 01  USERID PIC X(11) VALUE "SCOTT/TIGER".
 LINKAGE SECTION.
 01  CTX1 SQL-CONTEXT.
 PROCEDURE DIVISION USING CTX1.

     EXEC SQL CONTEXT USE :CTX1 END-EXEC.
     EXEC SQL CONNECT :USERID END-EXEC.
     EXEC SQL SELECT ...
 ...

Example 3

The following example uses multiple threads. Each thread has its own context. If the threads are to be executed concurrently, each thread must have its own context. Contexts are passed to the thread with the USING CLAUSE of the START statement and are declared in the LINKAGE SECTION of the threaded subprogram.

 IDENTIFICATION DIVISION.
 PROGRAM-ID. MAIN.
 ...
 DATA DIVISION.

 01  CTX1 SQL-CONTEXT.
 01  CTX2 SQL-CONTEXT.

 PROCEDURE DIVISION.
 ...
     EXEC SQL ENABLE THREADS END-EXEC.
     EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
     EXEC SQL CONTEXT ALLOCATE :CTX2 END-EXEC.

* include your code to start thread "SUBPGM" using CTX1 here.
* include your code to start thread "SUBPGM" using CTX2 here.
 ...

The thread SUBPGM is placed in another file:

PROGRAM-ID. SUBPGM.
 ...
 DATA DIVISION.
 ...
 01  USERID PIC X(11) VALUE "SCOTT/TIGER".
 ...
 LINKAGE SECTION.
 01  CTX SQL-CONTEXT.
 PROCEDURE DIVISION USING CTX.
     EXEC SQL CONTEXT USE :CTX END-EXEC.
     EXEC SQL CONNECT :USERID END-EXEC.
     EXEC SQL SELECT ....
 ...

Example 4

The next example is based on the previous example, but does the connection in the top level program and passes the connection with the context to the threaded subprogram.

 IDENTIFICATION DIVISION.
 PROGRAM-ID. MAIN.
 ...
 DATA DIVISION.

 01  CTX1 SQL-CONTEXT.
 01  CTX2 SQL-CONTEXT.
 01  USERID PIC X(11) VALUE "SCOTT/TIGER".

 ROCEDURE DIVISION.

     EXEC SQL ENABLE THREADS END-EXEC.
     EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
     EXEC SQL CONTEXT ALLOCATE :CTX2 END-EXEC.
     EXEC SQL CONTEXT USE :CTX1 END-EXEC.
     EXEC SQL CONNECT :USERID END-EXEC.
     EXEC SQL CONTEXT USE :CTX2 END-EXEC.
     EXEC SQL CONNECT :USERID END-EXEC.

* include your code to start thread "SUBPGM" using CTX1 here.
* include your code to start thread "SUBPGM" using CTX2 here.
 ...

The thread SUBPRGM is in another file:

 PROGRAM-ID. SUBPGM.
 ...
 LINKAGE SECTION.
 01  CTX SQL-CONTEXT.
 PROCEDURE DIVISION USING CTX.
     EXEC SQL CONTEXT USE :CTX END-EXEC.
     EXEC SQL SELECT ....
 ...

Example 5

The following example shows multiple threads which share a context. Note that in this case, the threads must be serialized.

 IDENTIFICATION DIVISION.
 PROGRAM-ID. MAIN.
 ...
 DATA DIVISION.

 01  CTX1 SQL-CONTEXT.

 PROCEDURE DIVISION.

     EXEC SQL ENABLE THREADS END-EXEC.
     EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.

* include your code to start thread1 "SUBPGM1" using CTX1 here.
* include your code to wait for thread1 here.
* include your code to start thread2 "SUBPGM2" using CTX1 here.
 ...

There are two separate files for the two threads. First there is:

 PROGRAM-ID. SUBPGM1.
 ...
 DATA DIVISION.
 ..
 01  USERID PIC X(11) VALUE "SCOTT/TIGER".
 ...
 LINKAGE SECTION.
 01  CTX SQL-CONTEXT.
 PROCEDURE DIVISION USING CTX.
     EXEC SQL CONTEXT USE :CTX END-EXEC.
 ...
     EXEC SQL CONNECT :USERID END-EXEC.

Another file contains SUBPGM2:

 PROGRAM-ID. SUBPGM2.
 ...
 DATA DIVISION.
 ...
 LINKAGE SECTION.
 01  CTX SQL-CONTEXT.
 PROCEDURE DIVISION USING CTX.
     EXEC SQL CONTEXT USE :CTX END-EXEC.
     EXEC SELECT ....
 ...

Multithreaded Example

This multi-file application demonstrates one way to use the SQLLIB runtime context area (SQL-CONTEXT) to support multiple threads. Precompile with THREADS=YES.

The main program, orathrd2, declares an array of S9(9) COMP variables to be used to hold the sqllib contexts. It enables threading through the

EXEC SQL ENABLE THREADS END-EXEC. 

statement and then calls the subprogram oracon (in file oracon.pco) to allocate the threads. oracon also establishes a connection for each allocated context.

Next, ORTHRD2 passes the context to one of the threaded entry points, THREAD-1 or THREAD-2. THREAD-1 simply selects and displays the salary for an employee. THREAD-2 selects and updates the salary for that employee. Since THREAD-2 issues a commit, the update is visible to threads that do the SELECT after it has committed. (But not those which run concurrently with the update.) Note that the output will vary from run to run because the timing of the update and commit is non-determinant.

It is important to remember that concurrent threads must each have their own contexts. Contexts may be passed to and used by subsequent threads, but threads may not use the same context concurrently. This model could be used for connection pooling, where the maximum number of connections are created initially and passed to threads as available, to execute user's requests.

An array of S9(9) COMP variables is used because you cannot currently declare an array of SQL-CONTEXT.

Note: This program was developed specifically for a Sun workstation running Solaris and MicroFocus ServerExpress compiler and uses vendor-specific directives and functionality.

See your platform-specific documentation for the specific COBOL statements that support multithreading.

The main program is in file orathrd2.pco:

      $SET REENTRANT MF
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ORATHRD2.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       78 MAX-LOOPS            VALUE 10.
       01 THREAD-ID            USAGE POINTER.
       01 TP-1                 USAGE THREAD-POINTER OCCURS MAX-LOOPS.
       01 IDEN-4               PIC 9(4).
       01 LOOP-COUNTER         PIC 9(2)  COMP-X EXTERNAL.
       01 PEMPNO               PIC S9(4) COMP EXTERNAL.
       01 ISAL                 PIC S9(4) COMP   VALUE ZERO.
           EXEC SQL
                INCLUDE SQLCA
           END-EXEC.
       THREAD-LOCAL-STORAGE SECTION.
       01  CONTEXT-AREA          PIC S9(9) COMP OCCURS MAX-LOOPS.
       PROCEDURE DIVISION.
       MAIN SECTION.
                
           PERFORM INITIALISATION
           PERFORM ORACLE-CONNECTIONS VARYING LOOP-COUNTER
                   FROM 1 BY 1 UNTIL LOOP-COUNTER > MAX-LOOPS
           PERFORM  VARYING LOOP-COUNTER FROM 1 BY 1
              UNTIL LOOP-COUNTER > MAX-LOOPS
               PERFORM START-THREAD
           END-PERFORM
           STOP RUN.

      *---------------------------------------------------------------
      * CHECK THAT WE ARE RUNNING UNDER A MULTI THREADED RTS.
      *---------------------------------------------------------------
       INITIALISATION SECTION.

           CALL "CBL_THREAD_SELF" USING THREAD-ID ON EXCEPTION
                DISPLAY "NO THREAD SUPPORT IN THIS RTS"
                STOP RUN
           END-CALL
           IF RETURN-CODE = 1008
                DISPLAY "CANNOT RUN THIS TEST ON SINGLE THREADED RTS"
                STOP RUN
           END-IF
           DISPLAY "MULTI-THREAD RTS"

      * ENABLING THREADS MUST BE DONE ONCE BEFORE ANY CONTEXT USEAGE
           EXEC SQL ENABLE THREADS END-EXEC.
           IF SQLCODE NOT = ZERO
              DISPLAY 'ERROR ENABLING ORACLE THREAD SUPPORT '
                      ' - ABORTING : ' SQLERRMC
              STOP RUN
           END-IF

      *  SET A VALUE FOR THE EMPLOYEE NUMBER.  BECAUSE THIS IS AN
      *  EXTERNAL VARIABLE, A COPY OF ITS VALUE IS VISIBLE TO THE 
      *  OTHER MODULES IN THIS APPLICATION
           MOVE 7566 TO PEMPNO
           EXIT SECTION.

      *-----------------------------------------------------------------
      * CREATE THREADS AND START WITH EITHER THREAD-1 OR THREAD-2
      *-----------------------------------------------------------------
       START-THREAD SECTION.

           IF LOOP-COUNTER = 2 OR LOOP-COUNTER = 5
              START "THREAD-2 "
                 USING CONTEXT-AREA(LOOP-COUNTER)
                 IDENTIFIED BY TP-1(LOOP-COUNTER)
                 STATUS IS IDEN-4
                 ON EXCEPTION DISPLAY "THREAD CREATE FAILED"
              END-START
              IF IDEN-4 NOT = ZERO
                DISPLAY "THREAD CREATE FAILED RETURNED " IDEN-4
              END-IF
           ELSE
              START "THREAD-1 "
                 USING CONTEXT-AREA(LOOP-COUNTER)
                 IDENTIFIED BY TP-1(LOOP-COUNTER)
                 STATUS IS IDEN-4
                 ON EXCEPTION DISPLAY "THREAD CREATE FAILED"
              END-START
              IF IDEN-4 NOT = ZERO
                DISPLAY "THREAD CREATE FAILED RETURNED " IDEN-4
              END-IF
           END-IF.

       START-THREAD-END.
           EXIT SECTION.


      *-----------------------------------------------------------------
      * ALLOCATE CONTEXT AREAS ESTABLISH CONNECTION WITH EACH AREA.
      *-----------------------------------------------------------------
       ORACLE-CONNECTIONS SECTION.

           CALL "ORACON" USING CONTEXT-AREA(LOOP-COUNTER).
       ORACLE-CONNECTIONS-END.
           EXIT SECTION.

Here is the file thread-1.pco:

      * This is Thread 1.  It selects and displays the data for 
      * the employee. The context area upon which a connection
      * has been established is passed to the thread through the 
      * linkage section. In a multi-file application, you
      * can pass the context through the linkage section.  
      * Precompile with THREADS=YES.
      * 
      $SET REENTRANT MF
       IDENTIFICATION DIVISION.
       PROGRAM-ID. THREAD-1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 PEMPNO               PIC S9(4) COMP EXTERNAL.

       LOCAL-STORAGE SECTION.
       01 DEMPNO               PIC Z(4) VALUE ZERO.
       01 PEMP-NAME1           PIC X(15) VARYING  VALUE SPACES.
       01 PSAL-VALUE1          PIC S9(7)V99 COMP-3 VALUE ZERO.
       01 ISAL1                PIC S9(4)   COMP   VALUE ZERO.
       01 DSAL-VALUE           PIC +(7).99 VALUE ZERO.
           EXEC SQL
                INCLUDE SQLCA
           END-EXEC.

       LINKAGE SECTION.
       01 CONTEXT-AREA1         SQL-CONTEXT.

      *---------------------------------------------------------------
      * USING THE PASSED IN CONTEXT, SELECT AND DISPLAY THE
      * DATA FOR EMPLOYEE.  
      *---------------------------------------------------------------
       PROCEDURE DIVISION USING CONTEXT-AREA1.
       MAIN SECTION.

           EXEC SQL WHENEVER SQLERROR GOTO SELECT-ERROR END-EXEC
           EXEC SQL CONTEXT USE :CONTEXT-AREA1 END-EXEC
           EXEC SQL
                SELECT  ENAME, SAL
                  INTO  :PEMP-NAME1, :PSAL-VALUE1:ISAL1
                  FROM  EMP
                 WHERE  EMPNO = :PEMPNO
           END-EXEC
           IF ISAL1 < ZERO
              MOVE ZERO     TO PSAL-VALUE1
           END-IF
           MOVE PEMPNO      TO DEMPNO
           MOVE PSAL-VALUE1 TO DSAL-VALUE
           DISPLAY "FOR EMP ", DEMPNO, " NAME ",
                   PEMP-NAME1-ARR(1:PEMP-NAME1-LEN),
                   " THE CURRENT SALARY IS ", DSAL-VALUE
           EXIT PROGRAM.


      *---------------------------------------------------------------
      * THERE HAS BEEN AN ERROR WHEN SELECTING FROM THE EMP TABLE
      *---------------------------------------------------------------
       SELECT-ERROR SECTION.

           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC
           DISPLAY "HIT AN ORACLE ERROR SELECTING EMPNO 7566"
           DISPLAY "SQLCODE = ", SQLCODE
           DISPLAY "ERROR TEXT ", SQLERRMC(1:SQLERRML)
           GOBACK
           EXIT SECTION.

Here is the file thread-2.pco:

      * This is Thread 2.  The program will select, then update,
      * increment, and then commit the salary.  It uses the passed-in 
      * context upon which a connection has previously been established.
      * Precompile with THREADS=YES.
      *
      $SET REENTRANT MF
       IDENTIFICATION DIVISION.
       PROGRAM-ID. THREAD-2.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 PEMPNO               PIC S9(4)   COMP EXTERNAL.

       LOCAL-STORAGE SECTION.
       01 DEMPNO               PIC Z(4) VALUE ZERO.
       01 PEMP-NAME2           PIC X(15) VARYING  VALUE SPACES.
       01 PSAL-VALUE2          PIC S9(7)V99 COMP-3 VALUE 100.
       01 ISAL2                PIC S9(4)   COMP   VALUE ZERO.
       01 DSAL-VALUE           PIC +(7).99 VALUE ZERO.
           EXEC SQL
                INCLUDE SQLCA
           END-EXEC.

       LINKAGE SECTION.
       01 CONTEXT-AREA2         SQL-CONTEXT.

      *---------------------------------------------------------------
      * USING THE PASSED IN CONTEXT AREA, FIRST SELECT TO GET INITIAL
      * VALUES, INCREMENT THE SALARY, UPDATE AND COMMIT.
      *---------------------------------------------------------------
       PROCEDURE DIVISION USING CONTEXT-AREA2.
       MAIN SECTION.

           EXEC SQL WHENEVER SQLERROR GOTO UPDATE-ERROR END-EXEC
           EXEC SQL CONTEXT USE     :CONTEXT-AREA2 END-EXEC
           EXEC SQL
                SELECT  ENAME, SAL
                  INTO  :PEMP-NAME2, :PSAL-VALUE2:ISAL2
                  FROM  EMP
                 WHERE  EMPNO = :PEMPNO
           END-EXEC
           ADD  10  TO PSAL-VALUE2
           EXEC SQL
                   UPDATE  EMP
                      SET  SAL   = :PSAL-VALUE2
                    WHERE  EMPNO = :PEMPNO
           END-EXEC
           MOVE PEMPNO      TO DEMPNO
           MOVE PSAL-VALUE2 TO DSAL-VALUE
           DISPLAY "FOR EMP ", DEMPNO, " NAME ",
                   PEMP-NAME2-ARR(1:PEMP-NAME2-LEN),
                   " THE UPDATED SALARY IS ", DSAL-VALUE
      *    THIS COMMIT IS REQUIRED, OTHERWISE THE DATABASE
      *    WILL BLOCK SINCE THE UPDATES ARE TO THE SAME ROW
           EXEC SQL COMMIT WORK END-EXEC
           EXIT PROGRAM.

      *---------------------------------------------------------------
      * THERE HAS BEEN AN ERROR WHEN UPDATING THE SAL IN THE EMP TABLE
      *---------------------------------------------------------------
       UPDATE-ERROR SECTION.

           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC
           \DISPLAY "HIT AN ORACLE ERROR UPDATING EMPNO 7566"
           DISPLAY "SQLCODE = ", SQLCODE
           DISPLAY "ERROR TEXT ", SQLERRMC(1:SQLERRML)
           GOBACK
           EXIT SECTION.

The file oracon.pco follows:

      * This program allocates SQLLIB runtime contexts, stores
      * a pointer to the context in the variable which was
      * passed in from the main program through the linkage section,
      * and establishes a connection on the allocated context.
      *
      * This program is written for Merant MicroFocus COBOL and uses
      * vendor-specific directives and functionality. Precompile
      * with THREADS=YES.
      *
      $SET REENTRANT MF
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ORACON.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 LOGON-STRING         PIC X(40)          VALUE SPACES.
           EXEC SQL
                INCLUDE SQLCA
           END-EXEC.
       LINKAGE SECTION.
       01  CONTEXT          SQL-CONTEXT.

       PROCEDURE DIVISION USING CONTEXT.
       MAIN SECTION.
                
      *-----------------------------------------------------------------
      * ALLOCATE CONTEXT AREAS ESTABLISH CONNECTION WITH EACH AREA.
      *-----------------------------------------------------------------
       ORACLE-CONNECTION SECTION.

           MOVE "SCOTT/TIGER"  TO LOGON-STRING
           EXEC SQL CONTEXT ALLOCATE :CONTEXT END-EXEC
           IF SQLCODE NOT = ZERO
              DISPLAY 'ERROR ALLOCATING CONTEXT '
                      '- ABORTING : ' SQLERRMC
              GOBACK
           ELSE
              DISPLAY 'CONTEXT ALLOCATED'
           END-IF

           EXEC SQL CONTEXT USE :CONTEXT END-EXEC
           EXEC SQL  CONNECT    :LOGON-STRING  END-EXEC
           IF SQLCODE NOT = ZERO
              DISPLAY 'ERROR CONNECTING SECOND THREAD TO THE DATABASE '
                      '- ABORT TEST : ' SQLERRMC
              GOBACK
           ELSE
              DISPLAY 'CONNECTION ESTABLISHED'
           END-IF
           EXIT SECTION.
PKF&]PKFJOEBPS/pcoafemb.htm Embedded SQL Statements and Precompiler Directives

E Embedded SQL Statements and Precompiler Directives

This appendix describes Oracle embedded SQL statements and directives. These statements and directives are prefaced in your source code with the keywords, EXEC SQL.

Note: Only statements which differ in syntax from non-embedded SQL are described in this appendix. For details of the non-embedded SQL statements, see the Oracle Database SQL Language Reference.

This appendix contains the following sections:

Summary of Precompiler Directives and Embedded SQL Statements

Embedded SQL statements place DDL, DML, and Transaction Control statements within a procedural language program. Embedded SQL is supported by the Oracle Precompilers. Table E-2 provides a functional summary of the embedded SQL statements and directives.

The Source/Type column in Table E-2 is displayed in the format source/type where:

Table E-1 Source/Type Column Meaning

SQL StatementsDirectives

source

Is either standard SQL (S) or an Oracle extension (O).

type

Is either an executable (E) statement or a directive (D).


Table E-2 Precompiler Directives and Embedded SQL Statements and Clauses

EXEC SQL StatementSource/TypePurpose

ALLOCATE

O/E

To allocate memory for a cursor variable, LOB locator or ROWID.

ALLOCATE DESCRIPTOR

S/E

To allocate a descriptor for ANSI dynamic SQL.

CALL

S/E

Call a stored procedure.

CLOSE

S/E

To disable a cursor.

COMMIT

S/E

To make all database changes permanent.

CONNECT

O/E

To log on to a database instance.

CONTEXT ALLOCATE

O/E

To allocate memory for a SQLLIB runtime context.

CONTEXT FREE

O/E

To free memory for a SQLLIB runtime context.

CONTEXT USE

O/E

To specify a SQLLIB runtime context.

DEALLOCATE DESCRIPTOR

S/E

To deallocate a descriptor area to free memory.

DECLARE CURSOR

S/D

To declare a cursor, associating it with a query.

DECLARE DATABASE

O/D

To declare an identifier for a nondefault database to be accessed in subsequent embedded SQL statements.

DECLARE STATEMENT

S/D

To assign a SQL variable name to a SQL statement.

DECLARE TABLE

O/D

To declare the table structure for semantic checking of embedded SQL statements by the Oracle Precompiler.

DELETE

S/E

To remove rows from a table or from a view's base table.

DESCRIBE

S/E

To initialize a descriptor, a structure holding host variable descriptions.

DESCRIBE DECRIPTOR

S/E

To obtain information about an ANSI SQL statement, and store it in a descriptor.

ENABLE THREADS

O/E

To initialize a process that supports multiple threads.

EXECUTE...END-EXEC

O/E

To execute an anonymous PL/SQL block.

EXECUTE

S/E

To execute a prepared dynamic SQL statement.

EXECUTE DESCRIPTOR

S/E

To execute a prepared statement using ANSI Dynamic SQL.

EXECUTE IMMEDIATE

S/E

To prepare and execute a SQL statement with no host variables.

FETCH

S/E

To retrieve rows selected by a query.

FETCH DESCRIPTOR

S/E

To retrieve rows selected by a query using ANSI Dynamic SQL.

FREE

S/E

To free memory used by a cursor, LOB locator, or ROWID.

GET DESCRIPTOR

S/E

To move information from an ANSI SQL descriptor area into host variables.

INSERT

S/E

To add rows to a table or to a view's base table.

LOB APPEND

O/E

To append a LOB to the end of another lOB.

LOB ASSIGN

O/E

To assign a LOB or BFILE locator to another locator.

LOB CLOSE

O/E

To close an open LOB or BFILE.

LOB COPY

O/E

To copy all or part of a LOB value into another LOB.

LOB CREATE TEMPORARY

O/E

To create a temporary LOB.

LOB DESCRIBE

O/E

To retrieve attributes from a LOB.

LOB DISABLE BUFFERING

O/E

To disable LOB buffering.

LOB ENABLE BUFFERING

O/E

To enable LOB buffering.

LOB ERASE

O/E

To erase a given amount of LOB data starting from a given offset.

LOB FILE CLOSE ALL

O/E

To close all open BFILE.

LOB FILE SET

O/E

To set DIRECTORY and FILENAME in a BFILE locator.

LOB FLUSH BUFFER

O/E

To write the LOB buffers to the database server.

LOB FREE TEMPORARY

O/E

To free temporary space for the LOB locator.

LOB LOAD

O/E

To copy all or part of a BFILE into an internal LOB.

LOB OPEN

O/E

To open a LOB or BFILE to read or read/write access.

LOB READ

O/E

To read all or part of a LOB or BFILE into a buffer.

LOB TRIM

O/E

To truncate a lob value.

LOB WRITE

O/E

To write the contents of a buffer to a LOB.

OPEN

S/E

To execute the query associated with a cursor.

OPEN DESCRIPTOR

S/E

To execute the query associated with a cursor in ANSI Dynamic SQL.

PREPARE

S/E

To parse a dynamic SQL statement.

ROLLBACK

S/E

To end the current transaction and discard all changes.

SAVEPOINT

S/E

To identify a point in a transaction to which you can later roll back.

SELECT

S/E

To retrieve data from one or more tables, views, or snapshots, assigning the selected values to host variables.

SET DESCRIPTOR

S/E

To set information in the ANSI SQL descriptor area from host variables.

UPDATE

S/E

To change existing values in a table or in a view's base table.

VAR

O/D

To override the default datatype and assign a specific Oracle external datatype to a host variable.

WHENEVER

S/D

To specify handling for error and warning conditions.


About the Statement Descriptions

The directives, and statements appear alphabetically. The description of each contains the following sections:

DirectivesDescription
PurposeDescribes the basic uses of the statement.
PrerequisitesLists privileges you must have and steps that you must take before using the statement. Unless otherwise noted, most statements also require that the database be open by your instance.
SyntaxShows the syntax diagram with the keywords and parameters of the statement.
Keywords and ParametersDescribes the purpose of each keyword and parameter.
Usage NotesDiscusses how and when to use the statement.
PrerequisitesLists privileges you must have and steps that you must take before using the statement. Unless otherwise noted, most statements also require that the database be open by your instance.
SyntaxShows the syntax diagram with the keywords and parameters of the statement.

How to Read Syntax Diagrams

Syntax diagrams are used to illustrate embedded SQL syntax. They are drawings that depict valid syntax.

Trace each diagram from left to right, in the direction shown by the arrows.

Statements keywords appear in UPPER CASE inside rectangles. Type them exactly as shown in the rectangles. Parameters appear in lower case inside ovals. Variables are used for the parameters. Operators, delimiters, and terminators appear inside circles.

If the syntax diagram has more than one path, you can choose any path to travel.

If you have the choice of more than one keyword, operator, or parameter, your options appear in a vertical list. In the following example, you can travel down the vertical line as far as you like, then continue along any horizontal line:

Syntax Diagrams

According to the diagram, all of the following statements are valid:

EXEC SQL WHENEVER NOT FOUND ... 
EXEC SQL WHENEVER SQLERROR ... 
EXEC SQL WHENEVER SQLWARNING ... 

Statement Terminator

In all Pro*COBOL EXEC SQL diagrams, each statement is understood to end with the token END-EXEC.

Required Keywords and Parameters

Required keywords and parameters can appear singly or in a vertical list of alternatives. Single required keywords and parameters appear on the main path, that is, on the horizontal line you are currently traveling. In the following example, cursor is a required parameter:

Required Keywords and Parameters

If there is a cursor named EMPCURSOR, then, according to the diagram, the following statement is valid:

EXEC SQL CLOSE EMPCURSOR END-EXEC. 

If any of the keywords or parameters in a vertical list appears on the main path, one of them is required. That is, you must choose one of the keywords or parameters, but not necessarily the one that appears on the main path. In the following example, you must choose one of the four actions:

Syntax Diagram

Optional Keywords and Parameters

If keywords and parameters appear in a vertical list preceding the main path, they are optional. In the following example, instead of traveling down a vertical line, you can continue along the main path:

Optional Keywords and Parameters

If there is a database named oracle2, then, according to the diagram, all of the following statements are valid:

     EXEC SQL ROLLBACK END-EXEC. 
     EXEC SQL ROLLBACK WORK END-EXEC. 
     EXEC SQL AT ORACLE2 ROLLBACK END-EXEC. 

Syntax Loops

Loops let you repeat the syntax within them as many times as you like. In the following example, column_name is inside a loop. So, after choosing one column name, you can go back repeatedly to choose another.

Syntax Loops

If DEBIT, CREDIT, and BALANCE are column names, then, according to the diagram, all of the following statements are valid:

EXEC SQL SELECT DEBIT INTO ... 
EXEC SQL SELECT CREDIT, BALANCE INTO ... 
EXEC SQL SELECT DEBIT, CREDIT, BALANCE INTO ... 

Multi-part Diagrams

Read a multi-part diagram as if all the main paths were joined end-to-end. The following example is a two-part diagram:

Multi-part Diagrams

According to the diagram, the following statement is valid:

     EXEC SQL PREPARE statement_name FROM :host_string END-EXEC. 

Oracle Names

The names of Oracle database objects, such as tables and columns, must not exceed 30 characters in length. The first character must be a letter, but the rest can be any combination of letters, numerals, dollar signs ($), pound signs (#), and underscores (_).

However, if a name is enclosed by quotation marks ("), it can contain any combination of legal characters, including spaces but excluding quotation marks.

Oracle names are not case-sensitive except when enclosed by quotation marks.

ALLOCATE (Executable Embedded SQL Extension)

Purpose

To allocate a cursor variable to be referenced in a PL/SQL block, or to allocate a LOB locator, or a ROWID .

Prerequisites

A cursor variable (see Chapter 6, "Embedded PL/SQL") of type SQL-CURSOR must be declared before allocating memory for the cursor variable.

Syntax

ALLOCATE

Keywords and Parameters

Keywords and ParametersDescription
cursor_variableA cursor variable of type SQL-CURSOR
host_ptrA variable of type SQL-ROWID for a ROWID, or SQL-BLOB, SQL-CLOB, or SQL-NCLOB for a LOB

Usage Notes

Whereas a cursor is static, a cursor variable is dynamic because it is not tied to a specific query. You can open a cursor variable for any type-compatible query.

For more information on this statement, see Oracle Database PL/SQL Language Reference and Oracle Database SQL Language Reference.

Example

This partial example illustrates the use of the ALLOCATE statement:

       ...
 01  EMP-CUR       SQL-CURSOR.
 01  EMP-REC.
     ...
     EXEC SQL ALLOCATE :EMP-CUR END-EXEC.
     ...

Related Topics

CLOSE (Executable Embedded SQL).

EXECUTE (Executable Embedded SQL).

FETCH (Executable Embedded SQL).

FREE (Executable Embedded SQL Extension).

ALLOCATE DESCRIPTOR (Executable Embedded SQL)

Purpose

An ANSI dynamic SQL statement that allocates a descriptor.

Prerequisites

None.

Syntax

ALLOCATE DESCRIPTOR

Keywords and Parameters

Keywords and ParametersDescription
array_size

integer

Host variable containing number of rows to be processed.

Number of rows to be processed.

descriptor_name

descriptor name

Host variable containing number of rows to be processed.

Number of rows to be processed.

GLOBAL | LOCALLOCAL (the default) means file scope, as opposed to GLOBAL, which means application scope.
WITH MAX integerMaximum number of host variables. The default is 100.

Usage Notes

Use DYNAMIC=ANSI precompiler option. For information on using this statement, see "ALLOCATE DESCRIPTOR".

Example

     EXEC SQL 
       FOR :batch ALLOCATE DESCRIPTOR GLOBAL :binddes WITH MAX 25 
     END-EXEC.

Related Topics

DESCRIBE DESCRIPTOR (Executable Embedded SQL).

GET DESCRIPTOR (Executable Embedded SQL).

SET DESCRIPTOR (Executable Embedded SQL).

CALL (Executable Embedded SQL)

Purpose

To call a stored procedure.

Prerequisites

An active database connection must exist.

Syntax

CALL

Keywords and Parameters

Keywords and ParametersDescription
schemaIs the schema containing the procedure. If you omit schema, Oracle assumes the procedure is in your own schema.
pkgThe package where the procedure is stored.
st_procThe stored procedure to be called.
db_linkThe complete or partial name of a database link to a remote database where the procedure is located. For information on referring to database links, see the Oracle Database SQL Language Reference.
exprThe list of expressions that are the parameters of the procedure.
ret_varThe host variable that receives the returned value of a function.
ret_indThe indicator variable for ret_var.

Usage Notes

For more about this statement, see Calling a Stored PL/SQL or Java Subprogram.

For a complete discussion of stored procedures, see: Oracle Database Advanced Application Developer's Guide, "External Routines" chapter.

Example

 ...
     05  EMP-NAME      PIC X(10) VARYING.
     05  EMP-NUMBER    PIC S9(4) COMP VALUE ZERO.
     05  SALARY        PIC S9(5)V99 COMP-3 VALUE ZERO.
...
      05  D-EMP-NUMBER  PIC 9(4).
...
      ACCEPT D-EMP-NUMBER.
      EXEC SQL 
        CALL mypkge.getsal(:EMP-NUMBER, :D-EMP-NUMBER, :EMP-NAME) INTO :SALARY 
      END-EXEC.
...

Related Topics

None

CLOSE (Executable Embedded SQL)

Purpose

To disable a cursor, freeing the resources acquired by opening the cursor, and releasing parse locks.

Prerequisites

The cursor or cursor variable must be open and MODE=ANSI.

Syntax

CLOSE

Keywords and Parameters

Keywords and ParametersDescription
cursorThe cursor to be closed
cursor_variableThe cursor variable to be closed.

Usage Notes

Rows cannot be fetched from a closed cursor. A cursor need not be closed to be reopened. The HOLD_CURSOR and RELEASE_CURSOR precompiler options alter the effect of the CLOSE statement. For information on these options, see Chapter 14, "Precompiler Options".

Example

This example illustrates the use of the CLOSE statement:

     EXEC SQL CLOSE EMP-CUR END-EXEC.

Related Topics

DECLARE CURSOR (Embedded SQL Directive).

OPEN (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

COMMIT (Executable Embedded SQL)

Purpose

To end your current transaction, making permanent all its changes to the database and optionally freeing all resources and disconnecting from the database server.

Prerequisites

To commit your current transaction, no privileges are necessary.

To manually commit a distributed in-doubt transaction that you originally committed, you must have FORCE TRANSACTION system privilege. To manually commit a distributed in-doubt transaction that was originally committed by another user, you must have FORCE ANY TRANSACTION system privilege.

Syntax

COMMIT

Keyword and Parameters

Keywords and ParametersDescription


ATIdentifies the database to which the COMMIT statement is issued. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement or used in a CONNECT statement.
host_variableIf you omit this clause, Oracle issues the statement to your default database.
WORKIs supported only for compliance with standard SQL. The statements COMMIT and COMMIT WORK are equivalent.
COMMENTSpecifies a comment to be associated with the current transaction. The 'text' is a quoted literal of up to 50 characters that Oracle stores in the data dictionary view DBA_2PC_PENDING along with the transaction ID if the transaction becomes in-doubt.
RELEASEFrees all resources and disconnects the application from the Oracle Server.
FORCEManually commits an in-doubt distributed transaction. The transaction is identified by the 'text' containing its local or global transaction ID. To find the IDs of such transactions, query the data dictionary view DBA_2PC_PENDING. You can also use the optional integer to explicitly assign the transaction a system change number (SCN). If you omit the integer, the transaction is committed using the current SCN.

Usage Notes

Always explicitly commit or rollback the last transaction in your program by using the COMMIT or ROLLBACK statement and the RELEASE option. Oracle automatically rolls back changes if the program terminates abnormally.

The COMMIT statement has no effect on host variables or on the flow of control in the program. For more information on this statement, see "Using the COMMIT Statement".

Example

This example illustrates the use of the embedded SQL COMMIT statement:

     EXEC SQL AT SALESDB COMMIT RELEASE END-EXEC.

Related Topics

ROLLBACK (Executable Embedded SQL).

SAVEPOINT (Executable Embedded SQL).

CONNECT (Executable Embedded SQL Extension)

Purpose

To logon to an Oracle database.

Prerequisites

You must have CREATE SESSION system privilege in the specified database.

Syntax

CONNECT

Keyword and Parameters

Keywords and ParametersDescription
user

password

Specifies your username and password separately.
user_passwordIs a single host variable containing the connect string username/password[@dbname].

To allow Oracle to verify your connection through your operating system, specify "/" as the :user_password value.

ATIdentifies the database to which the connection is made. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared db_name.
USINGSpecifies the Oracle Net database specification string used to connect to a nondefault database. If you omit this clause, you are connected to your default database.
ALTER AUTHORIZATIONChange password to the following string.
new_passwordNew password string.
IN SYSDBA MODE

IN SYSOPER MODE

Connect with SYSDBA or SYSOPER system privileges. Not allowed when ALTER AUTHORIZATION is used, or precompiler option AUTO_CONNECT is set to YES.

Usage Notes

A program can have multiple connections, but can only connect once to your default database. For more information on this statement, see: "Concurrent Logons".

Example

The following example illustrate the use of CONNECT:

     EXEC SQL CONNECT :USERNAME 
          IDENTIFIED BY :PASSWORD 
     END-EXEC.

You can also use this statement in which the value of :userid is the value of :username and :password separated by a "/" such as 'SCOTT/TIGER':

     EXEC SQL CONNECT :USERID END-EXEC.

Related Topics

COMMIT (Executable Embedded SQL).

DECLARE DATABASE (Oracle Embedded SQL Directive).

ROLLBACK (Executable Embedded SQL).

CONTEXT ALLOCATE (Executable Embedded SQL Extension)

Purpose

To initialize a SQLLIB runtime context that is referenced in an EXEC SQL CONTEXT USE statement.

Prerequisites

The runtime context must be declared of type SQL-CONTEXT.

Syntax

CONTEXT ALLOCATE

Keywords and Parameters

Keywords and ParametersDescription
contextThe SQLLIB runtime context for which memory is to be allocated.

Usage Notes

For more information on this statement, see "Embedded SQL Statements and Directives for Runtime Contexts".

Example

This example illustrates the use of a CONTEXT ALLOCATE statement in a Pro*COBOL embedded SQL program:

     EXEC SQL CONTEXT ALLOCATE :ctx1 END-EXEC.

Related Topics

CONTEXT FREE (Executable Embedded SQL Extension).

CONTEXT USE (Oracle Embedded SQL Directive).

CONTEXT FREE (Executable Embedded SQL Extension)

Purpose

To free all memory associated with a runtime context and place a null pointer in the host program variable.

Prerequisites

The CONTEXT ALLOCATE statement must be used to allocate memory for the specified runtime context before the CONTEXT FREE statement can free the memory allocated for it.

Syntax

CONTEXT FREE

Keywords and Parameters

Keywords and ParametersDescription
contextThe allocated runtime context for which the memory is to be deallocated.

Usage Notes

For more information on this statement, see "Embedded SQL Statements and Directives for Runtime Contexts".

Example

This example illustrates the use of a CONTEXT FREE statement in a Pro*COBOL embedded SQL program:

     EXEC SQL CONTEXT FREE :ctx1 END-EXEC.


Related Topics

CONTEXT ALLOCATE (Executable Embedded SQL Extension).

CONTEXT USE (Oracle Embedded SQL Directive).

CONTEXT USE (Oracle Embedded SQL Directive)

Purpose

To instruct the precompiler to use the specified SQLLIB runtime context on subsequent executable SQL statements

Prerequisites

The runtime context specified by the CONTEXT USE directive must be previously declared.

Syntax

CONTEXT USE

Keywords and Parameters

Keywords and ParametersDescription
contextThe allocated runtime context to use for subsequent executable SQL statements that follow it. For example, after specifying in your source code which context to use (multiple contexts can be allocated), you can connect to the Oracle Server and perform database operations within the scope of that context.
DEFAULTIndicates that the global context is to be used.

Usage Notes

This statement has no effect on declarative statements such as EXEC SQL INCLUDE or EXEC ORACLE OPTION. It works similarly to the EXEC SQL WHENEVER directive in that it affects all executable SQL statements which positionally follow it in a given source file without regard to standard C scope rules.

For more information on this statement, see "Embedded SQL Statements and Directives for Runtime Contexts".

Example

This example illustrates the use of a CONTEXT USE directive in a Pro*COBOL program:

     EXEC SQL CONTEXT USE :ctx1 END-EXEC. 

Related Topics

CONTEXT ALLOCATE (Executable Embedded SQL Extension).

CONTEXT FREE (Executable Embedded SQL Extension).

DEALLOCATE DESCRIPTOR (Embedded SQL Statement)

Purpose

An ANSI dynamic SQL statement that deallocates a descriptor area to free memory.

Prerequisites

The descriptor specified by the DEALLOCATE DESCRIPTOR statement must be previously allocated using the ALLOCATE DESCRIPTOR statement.

Syntax

DEALLOCATE DESCRIPTOR

Keywords and Parameters

Keywords and ParametersDescription
GLOBAL | LOCALLOCAL (the default) means file scope, as opposed to GLOBAL, which means application scope.
descriptor_name

'descriptor name'

Host variable containing the name of the allocated ANSI descriptor.

Name of the allocated ANSI descriptor.


Usage Notes

Use DYNAMIC=ANSI precompiler option.

For more information on this statement, see "DEALLOCATE DESCRIPTOR".

Example

     EXEC SQL DEALLOCATE DESCRIPTOR GLOBAL 'SELDES'  END-EXEC. 

Related Topics

ALLOCATE DESCRIPTOR (Executable Embedded SQL).

DESCRIBE DESCRIPTOR (Executable Embedded SQL).

GET DESCRIPTOR (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

SET DESCRIPTOR (Executable Embedded SQL).

DECLARE CURSOR (Embedded SQL Directive)

Purpose

To declare a cursor, giving it a name and associating it with a SQL statement or a PL/SQL block.

Prerequisites

If you associate the cursor with an identifier for a SQL statement or PL/SQL block, you must have declared this identifier in a previous DECLARE STATEMENT statement.

Syntax

DECLARE CURSOR

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database on which the cursor is declared. The database can be identified by either:
db_nameDatabase identifier declared in a previous DECLARE DATABASE statement.
host_variableHost variable whose value is a previously declared db_name.

If you omit this clause, Oracle declares the cursor on your default database.

cursorName of the cursor to be declared.
WITH HOLDCursor remains open after a COMMIT. The cursor must not be declared for UPDATE.
SELECT statementIs a SELECT statement to be associated with the cursor. The following statement cannot contain an INTO clause.
statement_nameIdentifies a SQL statement or PL/SQL block to be associated with the cursor. The statement_name or block_name must be previously declared in a DECLARE STATEMENT statement.

Usage Notes

You must declare a cursor before referencing it in other embedded SQL statements. The scope of a cursor declaration is global within its precompilation unit and the name of each cursor must be unique in its scope. You cannot declare two cursors with the same name in a single precompilation unit.

You can reference the cursor in the WHERE clause of an UPDATE or DELETE statement using the CURRENT OF syntax, if the cursor has been opened with an OPEN statement and positioned on a row with a FETCH statement. For more information on this statement, see "WITH HOLD Clause in DECLARE CURSOR Statements".

By default, held cursors are closed after ROLLBACK to conform to SQL standard behavior. To have held cursors remain open after ROLLBACK for backward compatibility, set the command-line option, CWH_SQL99, to NO.

Example

This example illustrates the use of a DECLARE CURSOR statement:

     EXEC SQL DECLARE EMPCURSOR CURSOR 
         FOR SELECT ENAME, EMPNO, JOB, SAL 
         FROM EMP 
         WHERE DEPTNO = :DEPTNO 
     END-EXEC.

Related Topics

CLOSE (Executable Embedded SQL).

DECLARE DATABASE (Oracle Embedded SQL Directive).

DECLARE STATEMENT (Embedded SQL Directive).

DELETE (Executable Embedded SQL).

FETCH (Executable Embedded SQL).

OPEN (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

SELECT (Executable Embedded SQL).

UPDATE (Executable Embedded SQL).

DECLARE DATABASE (Oracle Embedded SQL Directive)

Purpose

To declare an identifier for a nondefault database to be accessed in subsequent embedded SQL statements.

Prerequisites

You must have access to a username on the nondefault database.

Syntax

DECLARE DATABASE

Keywords and Parameters

Keywords and ParametersDescription
db_nameThe identifier established for the nondefault database.

Usage Notes

You declare a db_name for a nondefault database so that other embedded SQL statements can refer to that database using the AT clause. Before issuing a CONNECT statement with an AT clause, you must declare a db_name for the nondefault database with a DECLARE DATABASE statement.

For more information on this statement, see "Using Username/Password".

Example

This example illustrates the use of a DECLARE DATABASE directive:

     EXEC SQL DECLARE ORACLE3 DATABASE END-EXEC.

Related Topics

COMMIT (Executable Embedded SQL)

CONNECT (Executable Embedded SQL Extension).

DECLARE CURSOR (Embedded SQL Directive).

DECLARE STATEMENT (Embedded SQL Directive).

DELETE (Executable Embedded SQL).

EXECUTE (Executable Embedded SQL).

EXECUTE IMMEDIATE (Executable Embedded SQL).

INSERT (Executable Embedded SQL).

SELECT (Executable Embedded SQL).

UPDATE (Executable Embedded SQL).

DECLARE STATEMENT (Embedded SQL Directive)

Purpose

To declare an identifier for a SQL statement or PL/SQL block to be used in other embedded SQL statements.

Prerequisites

None.

Syntax

DECLARE STATEMENT

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database on which the SQL statement or PL/SQL block is declared. The database can be identified by either:
db_nameDatabase identifier declared in a previous DECLARE DATABASE statement.
host_variableHost variable whose value is a previously declared db_name. If you omit this clause, Oracle Database declares the SQL statement or PL/SQL block on your default database.
statement_nameIs the declared identifier for the statement or PL/SQL block.

Usage Notes

You must declare an identifier for a SQL statement or PL/SQL block with a DECLARE STATEMENT statement only if a DECLARE CURSOR statement referencing the identifier appears physically (not logically) in the embedded SQL program before the PREPARE statement that parses the statement or block and associates it with its identifier.

The scope of a statement declaration is global within its precompilation unit, like a cursor declaration. For more information on this statement, see "DECLARE".

Example I

This example illustrates the use of the DECLARE STATEMENT statement:

     EXEC SQL AT REMOTEDB 
         DECLARE MYSTATEMENT STATEMENT 
     END-EXEC.
     EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING
     END-EXEC.
     EXEC SQL EXECUTE MYSTATEMENT END-EXEC.

Example II

In this example, the DECLARE STATEMENT statement is required because the DECLARE CURSOR statement precedes the PREPARE statement:

     EXEC SQL DECLARE MYSTATEMENT STATEMENT END-EXEC. 
     ...
     EXEC SQL DECLARE EMPCURSOR CURSOR FOR MYSTATEMENT END-EXEC. 
     ...
     EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING END-EXEC. 
     ...

Related Topics

CLOSE (Executable Embedded SQL).

DECLARE DATABASE (Oracle Embedded SQL Directive).

FETCH (Executable Embedded SQL).

OPEN (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

DECLARE TABLE (Oracle Embedded SQL Directive)

Purpose

To define the structure of a table or view, including each column's datatype, default value, and NULL or NOT NULL specification for semantic checking by the precompiler when option SQLCHECK=SEMANTICS (or FULL).

Prerequisites

None.

Syntax

DECLARE TABLE

Keywords and Parameters

Keywords and ParametersDescription
tableThe name of the declared table.
columnA column of the table.
datatypeThe datatype of a column. For information on Oracle datatypes, see "The Oracle Database 11g Datatypes".
NOT NULLSpecifies that a column cannot contain nulls.

Usage Notes

Datatypes can only use integers (not expressions) for length, precision, scale. For more information on using this statement, see "Specifying SQLCHECK=SEMANTICS".

Example

The following statement declares the PARTS table with the PARTNO, BIN, and QTY columns:

     EXEC SQL DECLARE PARTS TABLE 
         (PARTNO  NUMBER  NOT NULL, 
          BIN     NUMBER, 
          QTY     NUMBER) 
     END-EXEC.

Related Topics

None.

DELETE (Executable Embedded SQL)

Purpose

To remove rows from a table or from a view's base table.

Prerequisites

For you to delete rows from a table, the table must be in your own schema or you must have DELETE privilege on the table.

For you to delete rows from the base table of a view, the owner of the schema containing the view must have DELETE privilege on the base table. Also, if the view is in a schema other than your own, you must be granted DELETE privilege on the view.

The DELETE ANY TABLE system privilege also enables you to delete rows from any table or any view's base table.

Syntax

DELETE

where the DML Returning clause is:

return clause

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database to which the DELETE statement is issued. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared db_name. If you omit this clause, the DELETE statement is issued to your default database.
host_integer

integer

Limits the number of times the statement is executed if the WHERE clause contains array host variables. If you omit this clause, Oracle executes the statement once for each component of the smallest array.
schemaThe schema containing the table or view. If you omit schema, Oracle assumes the table or view is in your own schema.
table viewThe name of a table from which the rows are to be deleted. If you specify view, Oracle deletes rows from the view's base table.
dblinkThe complete or partial name of a database link to a remote database where the table or view is located. For information on referring to database links, see Chapter 2 of the Oracle Database SQL Language Reference. You can only delete rows from a remote table or view if you are using Oracle with the distributed option.

If you omit dblink, Oracle assumes that the table or view is located on the local database.

part_nameName of partition in the table
aliasThe alias assigned to the table. Aliases are generally used in DELETE statements with correlated queries.
WHERESpecifies which rows are deleted:

condition

CURRENT OF

If you omit this clause entirely, Oracle deletes all rows from the table or view.
DML returning clauseSee "DML Returning Clause" for a discussion.

Usage Notes

The host variables in the WHERE clause should be either all scalars or all arrays. If they are scalars, Oracle executes the DELETE statement only once. If they are arrays, Oracle executes the statement once for each set of array components. Each execution may delete zero, one, or multiple rows.

Array host variables in the WHERE clause can have different sizes. In this case, the number of times Oracle executes the statement is determined by the smaller of the following values:

If no rows satisfy the condition, no rows are deleted and the SQLCODE returns a NOT_FOUND condition.

The cumulative number of rows deleted is returned through the SQLCA. If the WHERE clause contains array host variables, this value reflects the total number of rows deleted for all components of the array processed by the DELETE statement.

If no rows satisfy the condition, Oracle returns an error through the SQLCODE of the SQLCA. If you omit the WHERE clause, Oracle raises a warning flag in the fifth component of SQLWARN in the SQLCA. For more information on this statement and the SQLCA, see "Using the SQL Communications Area".

You can use comments in a DELETE statement to pass instructions, or hints, to the Oracle optimizer. The optimizer uses hints to choose an execution plan for the statement. For more information on hints, see Oracle Database Performance Tuning Guide.

Example

This example illustrates the use of the DELETE statement:

     EXEC SQL DELETE FROM EMP
        WHERE DEPTNO = :DEPTNO
        AND JOB = :JOB
    END-EXEC.
    EXEC SQL DECLARE EMPCURSOR CURSOR
        FOR SELECT EMPNO, COMM
        FROM EMP
    END-EXEC.
    EXEC SQL OPEN EMPCURSOR END-EXEC.
    EXEC SQL FETCH EMPCURSOR
        INTO :EMP-NUMBER, :COMMISSION
    END-EXEC.
    EXEC SQL DELETE FROM EMP
        WHERE CURRENT OF EMPCURSOR
    END-EXEC. 

Related Topics

DECLARE DATABASE (Oracle Embedded SQL Directive).

DECLARE STATEMENT (Embedded SQL Directive).

DESCRIBE (Executable Embedded SQL)

Purpose

To initialize a descriptor to hold descriptions of host variables for an Oracle dynamic SQL statement or PL/SQL block.

Prerequisites

You must have prepared the SQL statement or PL/SQL block in a previous embedded SQL PREPARE statement.

Syntax

DESCRIBE

Keywords and Parameters

Keywords and ParametersDescription
BIND VARIABLES FORInitializes the descriptor to hold information about the input variables for the SQL statement or PL/SQL block.
SELECT LIST FORInitializes the descriptor to hold information about the select list of a SELECT statement.
-The default is SELECT LIST FOR.
statement_nameIdentifies a SQL statement or PL/SQL block previously prepared with a PREPARE statement.
descriptorThe name of the descriptor to be initialized.

Usage Notes

You must issue a DESCRIBE statement before manipulating the bind or select descriptor within an embedded SQL program.

You cannot describe both input variables and output variables into the same descriptor.

The number of variables found by a DESCRIBE statement is the total number of placeholders in the prepare SQL statement or PL/SQL block, rather than the total number of uniquely named placeholders. For more information on this statement, see "The DESCRIBE Statement".

Example

This example illustrates the use of the DESCRIBE statement in a Pro*COBOL embedded SQL program:

     EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING END-EXEC. 
     EXEC SQL DECLARE EMPCURSOR 
         FOR SELECT EMPNO, ENAME, SAL, COMM 
         FROM EMP 
         WHERE DEPTNO = :DEPT-NUMBER 
     END-EXEC.
     EXEC SQL DESCRIBE BIND VARIABLES FOR MYSTATEMENT 
         INTO BINDDESCRIPTOR
     END-EXEC. 
     EXEC SQL OPEN EMPCURSOR 
         USING BINDDESCRIPTOR
     END-EXEC. 
     EXEC SQL DESCRIBE SELECT LIST FOR MY-STATEMENT 
         INTO SELECTDESCRIPTOR
     END-EXEC. 
     EXEC SQL FETCH EMPCURSOR 
         INTO SELECTDESCRIPTOR
     END-EXEC. 

Related Topics

PREPARE (Executable Embedded SQL).

DESCRIBE DESCRIPTOR (Executable Embedded SQL)

Purpose

Used to obtain information about an ANSI SQL statement, and to store it in a descriptor.

Prerequisites

You must have prepared the SQL statement in a previous embedded SQL PREPARE statement.

Syntax

DESCRIBE DESCRIPTOR

Keywords and Parameters

Keywords and ParametersDescription
statement_idThe name of the previously prepared SQL statement or PL/SQL block. OUTPUT is the default.
desc_nameHost variable containing the name of the descriptor that will hold information about the SQL statement.
'descriptor name'Name of the descriptor
GLOBAL | LOCALLOCAL is the default. It means file scope, as opposed to GLOBAL, which means application scope.

Usage Notes

Use DYNAMIC=ANSI precompiler option. Only COUNT and NAME are implemented for the INPUT descriptor.

The number of variables found by a DESCRIBE statement is the total number of place-holders in the prepare SQL statement or PL/SQL block, rather than the total number of uniquely named place-holders. For more information on this statement, see Chapter 10, "ANSI Dynamic SQL".

Example

     EXEC SQL PREPARE s FROM :my_stament END-EXEC. 
     EXEC SQL DESCRIBE INPUT s USING DESCRIPTOR 'in' END-EXEC. 

Related Topics

ALLOCATE DESCRIPTOR (Executable Embedded SQL).

DEALLOCATE DESCRIPTOR (Embedded SQL Statement).

GET DESCRIPTOR (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

SET DESCRIPTOR (Executable Embedded SQL).

ENABLE THREADS (Executable Embedded SQL Extension)

Purpose

To initialize a process that supports multiple threads.

Prerequisites

You must be developing a precompiler application for and compiling it on a platform that supports multithreaded applications, and THREADS=YES must be specified on the command line.

Syntax

ENABLE THREADS

Keywords and Parameters

None.

Usage Notes

The ENABLE THREADS statement must be executed once, and only once, before any other executable SQL statement and before spawning any threads. This statement does not require a host-variable specification.

Example

This example illustrates the use of the ENABLE THREADS statement in a Pro*COBOL program:

EXEC SQL ENABLE THREADS END-EXEC.

Related Topics

CONTEXT ALLOCATE (Executable Embedded SQL Extension).

CONTEXT FREE (Executable Embedded SQL Extension).

CONTEXT USE (Oracle Embedded SQL Directive).

EXECUTE ... END-EXEC (Executable Embedded SQL Extension)

Purpose

To embed an anonymous PL/SQL block into an Oracle Pro*COBOL program.

Prerequisites

None.

Syntax

EXECUTE ... END-EXEC

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database on which the PL/SQL block is executed. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared db_name.

If you omit this clause, the PL/SQL block is executed on your default database.
pl/sql_blockFor information on PL/SQL, including how to write PL/SQL blocks, see the Oracle Database PL/SQL Language Reference.
END-EXECMust appear after the embedded PL/SQL block.

Usage Notes

Since the Oracle Precompilers treat an embedded PL/SQL block like a single embedded SQL statement, you can embed a PL/SQL block anywhere in an Oracle Precompiler program that you can embed a SQL statement. For more information on embedding PL/SQL blocks in Oracle Precompiler programs, see Chapter 6, "Embedded PL/SQL".

Example

Placing this EXECUTE statement in an Oracle Precompiler program embeds a PL/SQL block in the program:

     EXEC SQL EXECUTE 
     BEGIN 
        SELECT ENAME, JOB, SAL 
            INTO :EMP-NAME:IND-NAME, :JOB-TITLE, :SALARY 
            FROM EMP 
            WHERE EMPNO = :EMP-NUMBER; 
        IF :EMP-NAME:IND-NAME IS NULL 
            THEN RAISE NAME-MISSING; 
        END IF; 
     END; 
     END-EXEC.

Related Topics

EXECUTE IMMEDIATE (Executable Embedded SQL).

EXECUTE (Executable Embedded SQL)

Purpose

In Oracle dynamic SQL, to execute a DELETE, INSERT, or UPDATE statement or a PL/SQL block that has been previously prepared with an embedded SQL PREPARE statement.

Prerequisites

You must first prepare the SQL statement or PL/SQL block with an embedded SQL PREPARE statement.

Syntax

EXECUTE

Keywords and Parameters

Keywords and ParametersDescription
FOR :array_size

FOR integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

Limits the number of times the statement is executed when the USING clause contains array host variables If you omit this clause, Oracle executes the statement once for each component of the smallest array.

statement_idA precompiler identifier associated with the SQL statement or PL/SQL block to be executed. Use the embedded SQL PREPARE statement to associate the precompiler identifier with the statement or PL/SQL block.
USING DESCRIPTOR SQLDA_descriptorUses an Oracle descriptor.

CANNOT be used together with an ANSI descriptor (INTO clause).

USINGSpecifies a list of host variables with optional indicator variables that Oracle substitutes as input variables into the statement to be executed. The host and indicator variables must be either all scalars or all arrays.
host_variableHost variables.
indicator_variableIndicator variables.

Usage Note

For more information on this statement, see Chapter 9, "Oracle Dynamic SQL".

Example

This example illustrates the use of the EXECUTE statement in a Pro*COBOL embedded SQL program:

     EXEC SQL PREPARE MY-STATEMENT FROM MY-STRING END-EXEC. 
     EXEC SQL EXECUTE MY-STATEMENT USING :MY-VAR END-EXEC. 

Related Topics

DECLARE DATABASE (Oracle Embedded SQL Directive).

PREPARE (Executable Embedded SQL).

EXECUTE DESCRIPTOR (Executable Embedded SQL

Purpose

In ANSI SQL Method 4, to execute a DELETE, INSERT, or UPDATE statement or a PL/SQL block that has been previously prepared with an embedded SQL PREPARE statement.

Prerequisites

You must first prepare the SQL statement or PL/SQL block with an embedded SQL PREPARE statement.

Syntax

EXECUTE DESCRIPTOR

Keywords and Parameters

Keywords and ParametersDescription
FOR :array_size

FOR integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

Limits the number of times the statement is executed. Oracle executes the statement once for each component of the smallest array.

statement_idA precompiler identifier associated with the SQL statement or PL/SQL block to be executed. Use the embedded SQL PREPARE statement to associate the precompiler identifier with the statement or PL/SQL block.
USING

descriptor_name

descriptor name

An ANSI input descriptor.

Host variable containing name of the input descriptor.

Name of the input descriptor.

INTO

descriptor_name

descriptor name

An ANSI output descriptor.

Host variable containing the name of the output descriptor.

Name of the output descriptor.

GLOBAL | LOCALLOCAL (the default) means file scope, as opposed to GLOBAL, which means application scope.

Usage Notes

For more information on this statement, see "EXECUTE".

Examples

The ANSI dynamic SQL Method 4 enables DML RETURNING in a SELECT to be supported by the INTO clause in EXECUTE:

EXEC SQL EXECUTE S2 USING DESCRIPTOR :bv1 INTO DESCRIPTOR 'SELDES' END-EXEC.

Related Topics

DECLARE DATABASE (Oracle Embedded SQL Directive).

PREPARE (Executable Embedded SQL).

EXECUTE IMMEDIATE (Executable Embedded SQL)

Purpose

To prepare and execute a DELETE, INSERT, or UPDATE statement or a PL/SQL block containing no host variables.

Prerequisites

None.

Syntax

EXECUTE IMMEDIATE

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database on which the SQL statement or PL/SQL block is executed. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared db_name.

If you omit this clause, the statement or block is executed on your default database.
host_stringA host variable whose value is the SQL statement or PL/SQL block to be executed.
textA text literal containing the SQL statement or PL/SQL block to be executed. The quotes may be omitted.

The SQL statement can only be a DELETE, INSERT, or UPDATE statement.

Usage Notes

When you issue an EXECUTE IMMEDIATE statement, Oracle parses the specified SQL statement or PL/SQL block, checking for errors, and executes it. If any errors are encountered, they are returned in the SQLCODE component of the SQLCA.

For more information on this statement, see "The EXECUTE IMMEDIATE Statement".

Example

This example illustrates the use of the EXECUTE IMMEDIATE statement:

     EXEC SQL
         EXECUTE IMMEDIATE 'DELETE FROM EMP WHERE EMPNO = 9460'
     END-EXEC. 

Related Topics

PREPARE (Executable Embedded SQL).

EXECUTE (Executable Embedded SQL).

FETCH (Executable Embedded SQL)

Purpose

To retrieve one or more rows returned by a query, assigning the select list values to host variables. For ANSI Dynamic SQL Method 4, see "FETCH DESCRIPTOR (Executable Embedded SQL)".

Prerequisites

You must first open the cursor with an the OPEN statement.

Syntax

FETCH

Keywords and Parameters

Keywords and ParametersDescription
FOR :array_size

FOR integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

Limits the number of rows fetched if you are using array host variables. If you omit this clause, Oracle fetches enough rows to fill the smallest array.

cursorA cursor that is declared by a DECLARE CURSOR statement. The FETCH statement returns one of the rows selected by the query associated with the cursor.
cursor_variableA cursor variable is allocated an ALLOCATE statement. The FETCH statement returns one of the rows selected by the query associated with the cursor variable.
INTOSpecifies a list of host variables and optional indicator variables into which data is fetched. These host variables and indicator variables must be declared within the program.
USING SQLDA_variableSpecifies the Oracle descriptor referenced in a previous DESCRIBE statement. Only use this clause with dynamic embedded SQL, method 4. The USING clause does not apply when a cursor variable is used.
host_variableThe host variable into which data is returned.
indicator_variableThe host indicator variable.

Usage Notes

The FETCH statement reads the rows of the active set and names the output variables which contain the results. Indicator values are set to -1 if their associated host variable is null.

The number of rows retrieved is specified by the size of the output host variables or the value specified in the FOR clause. The host variables to receive the data should be either all scalars or all arrays. If they are scalars, Oracle fetches only one row. If they are arrays, Oracle fetches enough rows to fill the arrays.

Array host variables can have different sizes. In this case, the number of rows Oracle fetches is determined by the smaller of the following values:

Of course, the number of rows fetched can be further limited by the number of rows that actually satisfy the query.

If a FETCH statement does not retrieve all rows returned by the query, the cursor is positioned on the next returned row. When the last row returned by the query has been retrieved, the next FETCH statement results in an warning code returned in the SQLCODE element of the SQLCA.

If the array is not completely filled then the warning is issued and you should check SQLERRD(3) to see how many rows were actually fetched.

Note that the FETCH statement does not contain an AT clause. You must specify the database accessed by the cursor in the DECLARE CURSOR statement.

You can only move forward through the active set with FETCH statements. If you want to revisit any of the previously fetched rows, you must reopen the cursor and fetch each row in turn. If you want to change the active set, you must assign new values to the input host variables in the cursor's query and reopen the cursor.

Example

This example illustrates the FETCH statement in a Pro*COBOL embedded SQL program:

     EXEC SQL DECLARE EMPCURSOR CURSOR FOR 
         SELECT JOB, SAL FROM EMP WHERE DEPTNO = 30
     END-EXEC. 
     ... 
     EXEC SQL WHENEVER NOT FOUND GOTO ... 
 LOOP. 
     EXEC SQL FETCH EMPCURSOR INTO :JOB-TITLE1, :SALARY1 END-EXEC. 
     EXEC SQL FETCH EMPCURSOR INTO :JOB-TITLE2, :SALARY2 END-EXEC. 
     ... 
     GO TO LOOP. 
     ... 

Related Topics

CLOSE (Executable Embedded SQL).

DECLARE CURSOR (Embedded SQL Directive).

OPEN (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

FETCH DESCRIPTOR (Executable Embedded SQL)

Purpose

To retrieve one or more rows returned by a query, assigning the select list values to host variables. Used in ANSI Dynamic SQL Method 4.

Prerequisites

You must first open the cursor with an the OPEN statement.

Syntax

FETCH DESCRIPTOR

Keywords and Parameters

Keywords and ParametersDescription
FOR :array_size

FOR integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

Limits the number of rows fetched if you are using array host variables. If you omit this clause, Oracle fetches enough rows to fill the smallest array.

cursorA cursor that is declared by a DECLARE CURSOR statement. The FETCH statement returns one of the rows selected by the query associated with the cursor.
cursor_variableA cursor variable is allocated an ALLOCATE statement. The FETCH statement returns one of the rows selected by the query associated with the cursor variable.
INTOSpecifies a list of host variables and optional indicator variables into which data is fetched. These host variables and indicator variables must be declared within the program.
INTO 'descriptor name'

INTO :descriptor_name

Name of the output ANSI descriptor.

Host variable containing the name of the output descriptor.

GLOBAL | LOCALLOCAL (the default) means file scope, as opposed to GLOBAL, which means application scope.

Usage Notes

The number of rows retrieved is specified by the size of the output host variables and the value specified in the FOR clause. The host variables to receive the data should be either all scalars or all arrays. If they are scalars, Oracle fetches only one row. If they are arrays, Oracle fetches enough rows to fill the arrays.

Array host variables can have different sizes. In this case, the number of rows Oracle fetches is determined by the smaller of the following values:

If a FETCH statement does not retrieve all rows returned by the query, the cursor is positioned on the next returned row. When the last row returned by the query has been retrieved, the next FETCH statement results in a warning code returned in the SQLCODE element of the SQLCA.

If the array is not completely filled then the warning is issued and you should check SQLERRD(3) to see how many rows were actually fetched.

Note that the FETCH statement does not contain an AT clause. You must specify the database accessed by the cursor in the DECLARE CURSOR statement.

You can only move forward through the active set with FETCH statements. If you want to revisit any of the previously fetched rows, you must reopen the cursor and fetch each row in turn. If you want to change the active set, you must assign new values to the input host variables in the cursor's query and reopen the cursor.

Use DYNAMIC=ANSI precompiler option for the ANSI SQL Method 4 application. For more information, see "FETCH" for the ANSI SQL Method 4 application.

Example

...
EXEC SQL ALLOCATE DESCRIPTOR 'output_descriptor' END-EXEC.
...
EXEC SQL PREPARE S FROM :dyn_statement END-EXEC.
EXEC SQL DECLARE mycursor CURSOR FOR S END-EXEC.
...
EXEC SQL FETCH mycursor INTO DESCRIPTOR 'output_descriptor' END-EXEC.
...

Related Topics

PREPARE statement.

FREE (Executable Embedded SQL Extension)

Purpose

To free memory used by a cursor, LOB locator, or ROWID.

Prerequisites

The memory has to have been already allocated.

Syntax

FREE

Keywords and Parameters

Keywords and ParametersDescription
cursor_variableA cursor variable that has previously been allocated in an ALLOCATE statement. It is of type SQL-CURSOR.

The FETCH statement returns one of the rows selected by the query associated with the cursor variable.

host_ptrA variable of type SQL-ROWID for a ROWID, or SQL-BLOB, SQL-CLOB, or SQL-NCLOB for a LOB.

Usage Notes

See "Cursors" and "Cursor Variables".

Example

* CURSOR VARIABLE EXAMPLE
...
 01  CUR      SQL-CURSOR.
...
     EXEC SQL ALLOCATE :CUR END-EXEC.
...
     EXEC SQL CLOSE :CUR END-EXEC.
     EXEC SQL FREE  :CUR END-EXEC.
...

Related Topics

ALLOCATE (Executable Embedded SQL Extension).

CLOSE (Executable Embedded SQL).

DECLARE CURSOR (Embedded SQL Directive).

GET DESCRIPTOR (Executable Embedded SQL)

Purpose

To obtain information about host variables from a SQL descriptor area.

Prerequisites

Use only with value semantics and ANSI dynamic SQL Method 4.

Syntax

GET DESCRIPTOR

where item_name can be one of these choices:

example

Keywords and Parameters

Keywords and ParametersDescription
array_size

integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

:descriptor_nameHost variable containing the name of the allocated ANSI descriptor.
'descriptor name'Name of the allocated ANSI descriptor.
GLOBAL | LOCALLOCAL (the default) means file scope, as opposed to GLOBAL, which means application scope.
host_var=COUNTHost variable containing the total number of input or output variables.
integerTotal number of input or output variables.
VALUE :host_integerHost variable containing the position of the referenced input or output variable.
VALUE integerThe position of the referenced input or output variable.
host_varHost variable which will receive the item's value.
item_nameThe item_name is found in Table 10-4, and Table 10-5, under the "Descriptor Item Name" column heading.

Usage Notes

Use DYNAMIC=ANSI precompiler option. The array size clause can be used with DATA, RETURNED_LENGTH, and INDICATOR item names. See "GET DESCRIPTOR".

Example

     EXEC SQL GET DESCRIPTOR GLOBAL 'mydesc' :mydesc_num_vars = COUNT END-EXEC.

Related Topics

ALLOCATE DESCRIPTOR (Executable Embedded SQL).

DESCRIBE DESCRIPTOR (Executable Embedded SQL).

SET DESCRIPTOR (Executable Embedded SQL).

INSERT (Executable Embedded SQL)

Purpose

To add rows to a table or to a view's base table.

Prerequisites

For you to insert rows into a table, the table must be in your own schema or you must have INSERT privilege on the table.

For you to insert rows into the base table of a view, the owner of the schema containing the view must have INSERT privilege on the base table. Also, if the view is in a schema other than your own, you must have INSERT privilege on the view.

The INSERT ANY TABLE system privilege also enables you to insert rows into any table or any view's base table.

Syntax

INSERT

where DML returning clause is:

return clause

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database on which the INSERT statement is executed. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared db_name. If you omit this clause, the INSERT statement is executed on your default database.
FOR :host_integerLimits the number of times the statement is executed if the VALUES clause contains array host variables. If you omit this clause, Oracle executes the statement once for each component in the smallest array.
schemaThe schema containing the table or view. If you omit schema, Oracle assumes the table or view is in your own schema.
table

view

The name of the table into which rows are to be inserted. If you specify view, Oracle inserts rows into the view's base table.
db_linkA complete or partial name of a database link to a remote database where the table or view is located. For information on referring to database links, see the Oracle Database SQL Language Reference. You can only insert rows into a remote table or view if you are using Oracle with the distributed option.

If you omit db_link, Oracle assumes that the table or view is on the local database.

part_nameThe name of partition in the table
columnA column of the table or view. In the inserted row, each column in this list is assigned a value from the VALUES clause or the query.

If you omit one of the table's columns from this list, the column's value for the inserted row is the column's default value as specified when the table was created. If you omit the column list altogether, the VALUES clause or query must specify values for all columns in the table.

VALUESSpecifies a row of values to be inserted into the table or view. See the syntax description of expr in the Oracle Database SQL Language Reference. Note that the expressions can be host variables with optional indicator variables. You must specify an expression in the VALUES clause for each column in the column list.
subqueryA subquery that returns rows that are inserted into the table. The select list of this subquery must have the same number of columns as the column list of the INSERT statement. For the syntax description of a subquery, see "SELECT" in the Oracle Database SQL Language Reference.
DML returning clauseSee "DML Returning Clause" for a discussion.

Usage Notes

Any host variables that appear in the WHERE clause should be either all scalars or all arrays. If they are scalars, Oracle executes the INSERT statement once. If they are arrays, Oracle executes the INSERT statement once for each set of array components, inserting one row each time.

Array host variables in the WHERE clause can have different sizes. In this case, the number of times Oracle executes the statement is determined by the smaller of the following values:

For more information on this statement, see "The Basic SQL Statements".

Example I

This example illustrates the use of the embedded SQL INSERT statement:

     EXEC SQL 
         INSERT INTO EMP (ENAME, EMPNO, SAL) 
         VALUES (:ENAME, :EMPNO, :SAL)
     END-EXEC. 

Example II

This example shows an embedded SQL INSERT statement with a subquery:

     EXEC SQL 
         INSERT INTO NEWEMP (ENAME, EMPNO, SAL) 
         SELECT ENAME, EMPNO, SAL FROM EMP
         WHERE DEPTNO = :DEPTNO
     END-EXEC. 

Related Topics

DECLARE DATABASE (Oracle Embedded SQL Directive).

LOB APPEND (Executable Embedded SQL Extension)

Purpose

To append a LOB to the end of another LOB.

Prerequisites

LOB buffering must not be enabled.The destination LOB must have been initialized.

Syntax

LOB APPEND

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "APPEND".

Related Topics

See the other LOB statements.

LOB ASSIGN (Executable Embedded SQL Extension)

Purpose

To assign a LOB or BFILE locator to another locator.

Syntax

LOB ASSIGN

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "ASSIGN".

Related Topics

See the other LOB statements.

LOB CLOSE (Executable Embedded SQL Extension)

Purpose

To close an open LOB or BFILE.

Syntax

LOB CLOSE

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "CLOSE" .

Related Topics

See the other LOB statements.

LOB COPY (Executable Embedded SQL Extension)

Purpose

To copy all or part of a LOB value into another LOB.

Syntax

LOB COPY

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "COPY".

Related Topics

See the other LOB statements.

LOB CREATE TEMPORARY (Executable Embedded SQL Extension)

Purpose

To create a temporary LOB.

Syntax

LOB CREATE TEMPORARY

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "CREATE TEMPORARY".

Related Topics

See the other LOB statements.

LOB DESCRIBE (Executable Embedded SQL Extension)

Purpose

To retrieve attributes from a LOB.

Syntax

LOB DESCRIBE

where attrib is:

example

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "DESCRIBE".

Related Topics

See the other LOB statements.

LOB DISABLE BUFFERING (Executable Embedded SQL Extension)

Purpose

To disable LOB buffering.

Syntax

LOB DISABLE BUFFERING

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "DISABLE BUFFERING".

Related Topics

See the other LOB statements.

LOB ENABLE BUFFERING (Executable Embedded SQL Extension)

Purpose

To enable LOB buffering.

Syntax

LOB ENABLE BUFFERING

Usage Notes

For usage notes as well as keywords, parameters, and examples, see ENABLE BUFFERING

Related Topics

See the other LOB statements.

LOB ERASE (Executable Embedded SQL Extension)

Purpose

To erase a given amount of LOB data starting from a given offset.

Syntax

LOB ERASE

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "ERASE".

Related Topics

See the other LOB statements.

LOB FILE CLOSE ALL (Executable Embedded SQL Extension)

Purpose

To close all open BFILEs in the current session.

Syntax

LOB FILE CLOSE ALL

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "FILE CLOSE ALL".

Related Topics

See the other LOB statements.

LOB FILE SET (Executable Embedded SQL Extension)

Purpose

To set DIRECTORY and FILENAME in a BFILE locator.

Syntax

LOB FILE SET

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "FILE SET".

Related Topics

See the other LOB statements.

LOB FLUSH BUFFER (Executable Embedded SQL Extension)

Purpose

To write the LOB buffers to the database server.

Syntax

LOB FLUSH BUFFER

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "FLUSH BUFFER".

Related Topics

See the other LOB statements.

LOB FREE TEMPORARY (Executable Embedded SQL Extension)

Purpose

To free temporary space for the LOB locator.

Syntax

LOB FREE TEMPORARY

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "FREE TEMPORARY".

Related Topics

See the other LOB statements.

LOB LOAD (Executable Embedded SQL Extension)

Purpose

To copy all or part of a BFILE into an internal LOB.

Syntax

LOB LOAD

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "LOAD FROM FILE".

Related Topics

See the other LOB statements.

LOB OPEN (Executable Embedded SQL Extension)

Purpose

To open a LOB or BFILE for read or read/write access.

Syntax

LOB OPEN

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "OPEN".

Related Topics

See the other LOB statements.

LOB READ (Executable Embedded SQL Extension)

Purpose

To read all or part of a LOB or BFILE into a buffer.

Syntax

LOB READ

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "READ".

Related Topics

See the other LOB statements.

LOB TRIM (Executable Embedded SQL Extension)

Purpose

To truncate a LOB value.

Syntax

LOB TRIM

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "TRIM".

Related Topics

See the other LOB statements.

LOB WRITE (Executable Embedded SQL Extension)

Purpose

To write the contents of a buffer to a LOB.

Syntax

LOB WRITE

Usage Notes

For usage notes as well as keywords, parameters, and examples, see "WRITE".

Related Topics

See the other LOB statements.

OPEN (Executable Embedded SQL)

Purpose

To open a cursor, evaluating the associated query and substituting the host variable names supplied by the USING clause into the WHERE clause of the query. It can be used in place of EXECUTE in dynamic SQL. For the ANSI Dynamic SQL syntax, see "OPEN DESCRIPTOR (Executable Embedded SQL)".

Prerequisites

You must declare the cursor with a DECLARE CURSOR embedded SQL statement before opening it.

Syntax

OPEN

Keywords and Parameters

Keywords and ParametersDescription
array_size

integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

Can only be used when the OPEN is equivalent to EXECUTE.

cursorThe (previously declared) cursor to be opened.
host_variableSpecifies a host variable with an optional indicator variable to be substituted into the statement associated with the cursor.

CANNOT be used together with an ANSI descriptor (INTO clause).

DESCRIPTOR SQLDA_descriptorSpecifies an Oracle descriptor that describes the host variables to be substituted into the WHERE clause of the associated query. The descriptor must be initialized in a previous DESCRIBE statement. The substitution is based on position. The host variable names specified in this statement can be different from the variable names in the associated query.

CANNOT be used together with an ANSI descriptor (INTO clause).


Usage Notes

The OPEN statement defines the active set of rows and initializes the cursor just before the first row of the active set. The values of the host variables at the time of the OPEN are substituted in the statement. This statement does not actually retrieve rows; rows are retrieved by the FETCH statement.

Once you have opened a cursor, its input host variables are not reexamined until you reopen the cursor. To change any input host variables and therefore the active set, you must reopen the cursor.

All cursors in a program are in a closed state when the program is initiated or when they have been explicitly closed using the CLOSE statement.

You can reopen a cursor without first closing it. For more information on this statement, see "Opening a Cursor".

Example

This example illustrates the use of the OPEN statement in a Pro*COBOL program:

     EXEC SQL DECLARE EMPCURSOR CURSOR FOR 
         SELECT ENAME, EMPNO, JOB, SAL 
         FROM EMP 
         WHERE DEPTNO = :DEPTNO
     END-EXEC. 
     EXEC SQL OPEN EMPCURSOR END-EXEC. 

Related Topics

CLOSE (Executable Embedded SQL) .

DECLARE CURSOR (Embedded SQL Directive) .

EXECUTE (Executable Embedded SQL).

FETCH (Executable Embedded SQL).

PREPARE (Executable Embedded SQL) .

OPEN DESCRIPTOR (Executable Embedded SQL)

Purpose

To open a cursor (for ANSI Dynamic SQL Method 4), evaluating the associated query and substituting the input host variable names supplied by the USING clause into the WHERE clause of the query. The INTO clause denotes the output descriptor. It can be used in place of EXECUTE in dynamic SQL.

Prerequisites

You must declare the cursor with a DECLARE CURSOR embedded SQL statement before opening it.

Syntax

OPEN DESCRIPTOR

Keywords and Parameters

Keywords and ParametersDescription
array_size

integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

Used only with dynamic SQL when it is equivalent to EXECUTE.

cursorThe (previously declared) cursor to be opened.
USING DESCRIPTOR

descriptor_name 'descriptor name'

Specifies an ANSI input descriptor with the host variable containing the name of the ANSI descriptor, or the name of the ANSI descriptor.
INTO DESCRIPTOR descriptor_name 'descriptor name'Specifies an ANSI output descriptor with the host variable containing the name of the ANSI descriptor, or the name of the ANSI descriptor.
GLOBAL | LOCALLOCAL (the default) means file scope, as opposed to GLOBAL, which means application scope.

Usage Notes

Set the precompiler option DYNAMIC to ANSI.

The OPEN statement defines the active set of rows and initializes the cursor just before the first row of the active set. The values of the host variables at the time of the OPEN are substituted in the statement. This statement does not actually retrieve rows; rows are retrieved by the FETCH statement.

Once you have opened a cursor, its input host variables are not reexamined until you reopen the cursor. To change any input host variables and therefore the active set, you must reopen the cursor.

All cursors in a program are in a closed state when the program is initiated or when they have been explicitly closed using the CLOSE statement.

You can reopen a cursor without first closing it. For more information on this statement, see "Inserting Rows".

Example

 01 DYN-STATEMENT PIC X(58) VALUE "SELECT ENAME, EMPNO FROM EMP WHERE
       DEPTNO =:DEPTNO-DAT".
 01 DEPTNO-DAT PIC S9(9) COMP VALUE 10.
 ...
     EXEC SQL ALLOCATE DESCRIPTOR 'input-descriptor' END-EXEC.
     EXEC SQL ALLOCATE DESCRIPTOR 'output-descriptor'
     ...
     EXEC SQL PREPARE S FROM :DYN-STATEMENT END-EXEC.
     EXEC SQL DECLARE C CURSOR FOR S END-EXEC.
     ...
     EXEC SQL OPEN C USING DESCRIPTOR 'input-descriptor' END-EXEC.
     ...

Related Topics

CLOSE (Executable Embedded SQL).

DECLARE CURSOR (Embedded SQL Directive).

FETCH DESCRIPTOR (Executable Embedded SQL) .

PREPARE (Executable Embedded SQL).

PREPARE (Executable Embedded SQL)

Purpose

To parse a SQL statement or PL/SQL block specified by a host variable and associate it with an identifier.

Prerequisites

None.

Syntax

PREPARE

Keywords and Parameters

Keywords and ParametersDescription
db_nameA null-terminated string containing the database connection name, as established previously in a CONNECT statement. If it is omitted, or if it is an empty string, the default database connection is assumed.
host_variableA host variable containing the name of the database connection.
array_size

integer

Host variable containing the number of rows to be processed.

Number of rows to be processed.

statement_idThe identifier to be associated with the prepared SQL statement or PL/SQL block. If this identifier was previously assigned to another statement or block, the prior assignment is superseded.
host_stringA host variable whose value is the text of a SQL statement or PL/SQL block to be prepared.
textA text literal containing the SQL statement or PL/SQL block to be executed. The quotes may be omitted.
select_commandA SELECT statement.

Usage Notes

Any variables that appear in the host_string or text are placeholders. The actual host variable names are assigned in the USING clause of the OPEN statement (input host variables) or in the INTO clause of the FETCH statement (output host variables).

A SQL statement is prepared only once, but can be executed any number of times.

Example

This example illustrates the use of a PREPARE statement in a Pro*COBOL embedded SQL program:

     EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING END-EXEC. 
     EXEC SQL EXECUTE MYSTATEMENT END-EXEC.

Related Topics

CLOSE (Executable Embedded SQL).

DECLARE CURSOR (Embedded SQL Directive).

FETCH (Executable Embedded SQL).

OPEN (Executable Embedded SQL).

ROLLBACK (Executable Embedded SQL)

Purpose

To undo work done in the current transaction. You can also use this statement to manually undo the work done by an in-doubt distributed transaction.

Prerequisites

To roll back your current transaction, no privileges are necessary.

To manually roll back an in-doubt distributed transaction that you originally committed, you must have FORCE TRANSACTION system privilege. To manually roll back an in-doubt distributed transaction originally committed by another user, you must have FORCE ANY TRANSACTION system privilege.

Syntax

ROLLBACK

Keywords and Parameters

Keywords and ParametersDescription
db_nameA null-terminated string containing the database connection name, as established previously in a CONNECT statement. If it is omitted, or if it is an empty string, the default database connection is assumed.
host_variableA host variable containing the name of the database connection.

If you omit this clause, the savepoint is created on your default database.
WORKIs optional and is provided for ANSI compatibility.
TORolls back the current transaction to the specified savepoint. If you omit this clause, the ROLLBACK statement rolls back the entire transaction.
FORCEManually rolls back an in-doubt distributed transaction. The transaction is identified by the text containing its local or global transaction ID. To find the IDs of such transactions, query the data dictionary view DBA_2PC_PENDING.

ROLLBACK statements with the FORCE clause are not supported in PL/SQL.

RELEASEFrees all resources and disconnects the application from the database server. The RELEASE clause is not allowed with SAVEPOINT and FORCE clauses.
savepointThe name of the savepoint to be rolled back to.

Usage Notes

A transaction (or a logical unit of work) is a sequence of SQL statements that Oracle treats as a single unit. A transaction begins with the first executable SQL statement after a COMMIT, ROLLBACK or connection to the database. A transaction ends with a COMMIT statement, a ROLLBACK statement, or disconnection (intentional or unintentional) from the database. Note that Oracle issues an implicit COMMIT statement before and after processing any data definition language statement.

Using the ROLLBACK statement without the TO SAVEPOINT clause performs the following operations:

Using the ROLLBACK statement with the TO SAVEPOINT clause performs the following operations:

It is recommended that you explicitly end transactions in application programs using either a COMMIT or ROLLBACK statement. If you do not explicitly commit the transaction and the program terminates abnormally, Oracle rolls back the last uncommitted transaction.

Example I

The following statement rolls back your entire current transaction:

     EXEC SQL ROLLBACK END-EXEC. 

Example II

The following statement rolls back your current transaction to savepoint SP5:

      EXEC SQL ROLLBACK TO SAVEPOINT SP5 END-EXEC.

Distributed Transactions

Oracle with the distributed option enables you to perform distributed transactions, or transactions that modify data on multiple databases. To commit or roll back a distributed transaction, you need only issue a COMMIT or ROLLBACK statement as you would any other transaction.

If there is a network failure during the commit process for a distributed transaction, the state of the transaction may be unknown, or in-doubt. After consultation with the administrators of the other databases involved in the transaction, you may decide to manually commit or roll back the transaction on your local database. You can manually roll back the transaction on your local database by issuing a ROLLBACK statement with the FORCE clause.

You cannot manually roll back an in-doubt transaction to a savepoint.

A ROLLBACK statement with a FORCE clause only rolls back the specified transaction. Such a statement does not affect your current transaction.

Example III

The following statement manually rolls back an in-doubt distributed transaction:

     EXEC SQL ROLLBACK WORK FORCE '25.32.87' END-EXEC.

Related Topics

COMMIT (Executable Embedded SQL).

SAVEPOINT (Executable Embedded SQL).

SAVEPOINT (Executable Embedded SQL)

Purpose

To identify a point in a transaction to which you can later roll back.

Prerequisites

None.

Syntax

SAVEPOINT

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database on which the savepoint is created. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared db_name. If you omit this clause, the savepoint is created on your default database.
savepointThe name of the savepoint to be created.

Usage Notes

For more information on this statement, see "Using the SAVEPOINT Statement".

Example

This example illustrates the use of the embedded SQL SAVEPOINT statement:

     EXEC SQL SAVEPOINT SAVE3 END-EXEC.

Related Topics

COMMIT (Executable Embedded SQL).

ROLLBACK (Executable Embedded SQL).

SELECT (Executable Embedded SQL)

Purpose

To retrieve data from one or more tables, views, or snapshots, assigning the selected values to host variables.

Prerequisites

For you to select data from a table or snapshot, the table or snapshot must be in your own schema or you must have SELECT privilege on the table or snapshot.

For you to select rows from the base tables of a view, the owner of the schema containing the view must have SELECT privilege on the base tables. Also, if the view is in a schema other than your own, you must have SELECT privilege on the view.

The SELECT ANY TABLE system privilege also enables you to select data from any table or any snapshot or any view's base table.

Syntax

SELECT

SELECT

Keywords and Parameters

Keywords and ParametersDescription
ATIdentifies the database to which the SELECT statement is issued. The database can be identified by either:
db_nameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared db_name.

If you omit this clause, the SELECT statement is issued to your defauaslt database.
select_listIdentical to the non-embedded SELECT statement except that a host variables can be used in place of literals.
INTOSpecifies output host variables and optional indicator variables to receive the data returned by the SELECT statement. Note that these variables must be either all scalars or all arrays, but arrays need not have the same size.
WHERERestricts the rows returned to those for which the condition is TRUE. See the syntax description of condition in the Oracle Database SQL Language Reference. The condition can contain host variables, but cannot contain indicator variables. These host variables can be either scalars or arrays.

All other keywords and parameters are identical to the non-embedded SQL SELECT statement.

Usage Notes

If no rows meet the WHERE clause condition, no rows are retrieved and Oracle returns an error code through the SQLCODE component of the SQLCA.

You can use comments in a SELECT statement to pass instructions, or hints, to the Oracle optimizer. The optimizer uses hints to choose an execution plan for the statement. For more information on hints, see Oracle Database Performance Tuning Guide.

Example

This example illustrates the use of the embedded SQL SELECT statement:

     EXEC SQL SELECT ENAME, SAL + 100, JOB 
         INTO :ENAME, :SAL, :JOB 
         FROM EMP 
         WHERE EMPNO = :EMPNO
     END-EXEC. 

Related Topics

DECLARE CURSOR (Embedded SQL Directive).

DECLARE DATABASE (Oracle Embedded SQL Directive).

EXECUTE (Executable Embedded SQL).

FETCH (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

SET DESCRIPTOR (Executable Embedded SQL)

Purpose

Use this ANSI dynamic SQL statement to set information in the descriptor area from host variables.

Prerequisites

Use after a DESCRIBE DESCRIPTOR.

Syntax

SET DESCRIPTOR

where item_name can be one of these choices:

SET DESCRIPTOR

Keywords and Parameters

Keywords and ParametersDescription
array_size

integer

Host variable containing the number of rows to be processed.

Number of rows to be processed. The array size clause can only be used with DATA, RETURNED_LENGTH and INDICATOR item names.

GLOBAL | LOCALLOCAL (the default) means file scope, as opposed to GLOBAL, which means application scope.
descriptor_name

'descriptor name'

Host variable containing the name of the allocated ANSI descriptor.

Name of the allocated ANSI descriptor.

COUNTThe total number of input or output variables.
VALUEThe position of the referenced host variable in the statement.
item_nameSee Table 10-6, and Table 10-7 for lists of the item_names, and their descriptions.
host_varHost variable containing the total number of input or output variables.
integerTotal number of input or output variables.
host_varThe host variables used to set the item.
REFReference semantics are to be used. Can be used only with RETURNED_LENGTH, DATA, and INDICATOR item names.

Must be used to set RETURNED_LENGTH.


Usage Notes

Use DYNAMIC=ANSI precompiler option. Set CHARACTER_SET_NAME to UTF16 for client-side Unicode support. See "SET DESCRIPTOR" for complete details, including tables of descriptor item names.

Example

     EXEC SQL SET DESCRIPTOR GLOBAL :mydescr COUNT = 3 END-EXEC.

Related Topics

ALLOCATE DESCRIPTOR (Executable Embedded SQL).

DEALLOCATE DESCRIPTOR (Embedded SQL Statement).

DESCRIBE DESCRIPTOR (Executable Embedded SQL).

GET DESCRIPTOR (Executable Embedded SQL).

PREPARE (Executable Embedded SQL).

UPDATE (Executable Embedded SQL)

Purpose

To change existing values in a table or in a view's base table.

Prerequisites

For you to update values in a table or snapshot, the table must be in your own schema or you must have UPDATE privilege on the table.

For you to update values in the base table of a view, the owner of the schema containing the view must have UPDATE privilege on the base table. Also, if the view is in a schema other than your own, you must have UPDATE privilege on the view.

The UPDATE ANY TABLE system privilege also enables you to update values in any table or any view's base table.

Syntax

UPDATE

where DML returning clause is:

UPDATE

Keywords and Parameters

Keywords and ParametersDescription
ATidentifies the database to which the UPDATE statement is issued. The database can be identified by either:
dbnameA database identifier declared in a previous DECLARE DATABASE statement.
host_variableA host variable whose value is a previously declared dbname.
-If you omit this clause, the UPDATE statement is issued to your default database.
FOR :host_integerLimits the number of times the UPDATE statement is executed if the SET and WHERE clauses contain array host variables. If you omit this clause, Oracle executes the statement once for each component of the smallest array.
schemaThe schema containing the table or view. If you omit schema, Oracle assumes the table or view is in your own schema.
table viewThe name of the table to be updated. If you specify view, Oracle updates the view's base table.
dblinkA complete or partial name of a database link to a remote database where the table or view is located. For information on referring to database links, see the Oracle Database SQL Language Reference. You can only use a database link to update a remote table or view if you are using Oracle with the distributed option.
part_nameName of partition in the table
aliasA name used to reference the table, view, or subquery elsewhere in the statement.
columnThe name of a column of the table or view that is to be updated. If you omit a column of the table from the SET clause, that column's value remains unchanged.
exprThe new value assigned to the corresponding column. This expression can contain host variables and optional indicator variables. See the syntax of expr in the Oracle Database SQL Language Reference.
subquery_1A subquery that returns new values that are assigned to the corresponding columns. For the syntax of a subquery, see "SELECT" in the Oracle Database SQL Language Reference.
subquery_2A subquery that return a new value that is assigned to the corresponding column. For the syntax of a subquery, see "SELECT" in the Oracle Database SQL Language Reference.
WHERESpecifies which rows of the table or view are updated:
-condition
-CURRENT OF
-If you omit this clause entirely, Oracle updates all rows of the table or view.
DML returning clauseSee "DML Returning Clause" for a discussion.

Usage Notes

Host variables in the SET and WHERE clauses must be either all scalars or all arrays. If they are scalars, Oracle executes the UPDATE statement only once. If they are arrays, Oracle executes the statement once for each set of array components. Each execution may update zero, one, or multiple rows.

Array host variables can have different sizes. In this case, the number of times Oracle executes the statement is determined by the smaller

of the following values:

The cumulative number of rows updated is returned through the third element of the SQLERRD component of the SQLCA. When arrays are used as input host variables, this count reflects the total number of updates for all components of the array processed in the UPDATE statement. If no rows satisfy the condition, no rows are updated and Oracle returns an error message through the SQLCODE element of the SQLCA. If you omit the WHERE clause, all rows are updated and Oracle raises a warning flag in the fifth component of the SQLWARN element of the SQLCA.

You can use comments in an UPDATE statement to pass instructions, or hints, to the Oracle optimizer. The optimizer uses hints to choose an execution plan for the statement. For more information on hints, see Oracle Database Performance Tuning Guide.

For more information on this statement, see "The Basic SQL Statements" andChapter 3, "Database Concepts".

Examples

The following examples illustrate the use of the embedded SQL UPDATE statement:

     EXEC SQL UPDATE EMP 
         SET SAL = :SAL, COMM = :COMM INDICATOR :COMM-IND 
         WHERE ENAME = :ENAME
     END-EXEC. 
 
     EXEC SQL UPDATE EMP 
         SET (SAL, COMM) = 
             (SELECT AVG(SAL)*1.1, AVG(COMM)*1.1 
             FROM EMP) 
         WHERE ENAME = 'JONES'
     END-EXEC. 

Related Topics

DECLARE DATABASE (Oracle Embedded SQL Directive).

VAR (Oracle Embedded SQL Directive)

Purpose

To perform host variable equivalencing, to assign a specific Oracle external datatype to an individual host variable, overriding the default datatype assignment. There is an optional clause, CONVBUFSZ, that specifies the size of a buffer for character set conversion.

Prerequisites

The host variable must be previously declared in the embedded SQL program.

Syntax

VAR

Keywords and Parameters

Keywords and ParametersDescription
host_variableThe host variable to be assigned an Oracle external datatype.
dtypAn Oracle external datatype recognized by Pro*COBOL (not an Oracle internal datatype). The datatype may include a length, precision, or scale. This external datatype is assigned to the host_variable. For a list of external datatypes, see "External Datatypes".
sizeThe size in bytes of a buffer in the Oracle runtime library used to perform conversion between character sets of the host_variable.

Usage Notes

Datatype equivalencing is useful for any of the following purposes:

For more information about Oracle datatypes, see "Sample Program 4: Datatype Equivalencing".

Example

This example equivalences the host variable DEPT_NAME to the datatype VARCHAR2 and the host variable BUFFER to the datatype RAW(200):

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 
     ... 
     01 DEPT-NAME  PIC X(15).
* -- default datatype is CHAR 
     EXEC SQL VAR DEPT-NAME IS VARCHAR2 END-EXEC.
* -- reset to STRING 
     ...
     01 BUFFER-VAR.
          05 BUFFER  PIC X(200).     
* -- default datatype is CHAR 
     EXEC SQL VAR BUFFER IS RAW(200) END-EXEC.
* -- refer to RAW 
     ...
     EXEC SQL END DECLARE SECTION END-EXEC. 

Related Topics

None.

WHENEVER (Embedded SQL Directive)

Purpose

To specify the action to be taken when an error or warning results from executing an embedded SQL program.

Prerequisites

None.

Syntax

WHENEVER

where DO.CALL.CLAUSE is:

WHENEVER

Keywords and Parameters

Keywords and ParametersDescription
NOT FOUND | NOTFOUNDIdentifies any exception condition that returns an error code of +1403 to SQLCODE (or a +100 code when MODE=ANSI).
SQLERRORIdentifies a condition that results in a negative return code.
SQLWARNINGIdentifies a non-fatal warning condition.
CONTINUEIndicates that the program should progress to the next statement.
GOTO | GO TOIndicates that the program should branch to the statement named by label.
STOPStops program execution.
DO PERFORMIndicates that the program should perform a paragraph or section at label.
DO CALLIndicates that the program should execute a subprogram.
subprogram_nameThe subprogram to be executed. It may have to be inside quotes (").
USINGIndicates that the parameters of the subprogram follow.
paramA list of subprogram parameters separated by blanks.

The WHENEVER directive enables your program to take one of several possible actions in the event an embedded SQL statement results in an error or warning.

The scope of a WHENEVER statement is positional, rather than logical. A WHENEVER statement applies to all embedded SQL statements that textually follow it in the source file, not in the flow of the program logic. A WHENEVER statement remains in effect until it is superseded by another WHENEVER statement checking for the same condition.

For more information about and examples of the conditions and actions of this directive, see "WHENEVER Directive".

Do not confuse the WHENEVER embedded SQL directive with the WHENEVER SQL*Plus command.

Example

The following example illustrates the use of the WHENEVER directive in a Pro*COBOL embedded SQL program:

     EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC.
     ... 
     EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC. 
     ... 
 SQL-ERROR. 
     EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. 
     DISPLAY "ORACLE ERROR DETECTED.".
     EXEC SQL ROLLBACK RELEASE END-EXEC.
     STOP RUN. 

Related Topics

None

PK@ysasPKFJOEBPS/pcoacres.htmQx Reserved Words, Keywords, and Namespaces

B Reserved Words, Keywords, and Namespaces

Topics in this appendix include:

Reserved Words and Keywords

Some words are reserved by Oracle. That is, they have a special meaning to Oracle and cannot be redefined. For this reason, you cannot use them to name database objects such as columns, tables, or indexes. To view the lists of the Oracle reserved words for SQL and PL/SQL, see the Oracle Database SQL Language Reference and the Oracle Database PL/SQL Language Reference.

Like COBOL keywords, you cannot use Pro*COBOL keywords as variables in your program(s). Otherwise, an error will be generated. An error may result if they are used as the name of a database object such as a column. Here are the keywords used in Pro*COBOL.

Keywords in Pro*COBOLKeywords in Pro*COBOLKeywords in Pro*COBOL
allallocatealter
analyzeandany
appendarraylenas
ascassignat
auditauthorizationavg
beginbetweenbind
bothbreakbuffer
bufferingbycall
castcharcharacter
character_set_namecharfcharz
checkchunksizeclose
commentcommitconnect
constraintconstraintscontext
continueconvbufszcopy
countcreatecurrent
currvalcursordata
databasedatedatetime_interval_code
datetime_interval_precisiondaydeallocate
decimaldeclaredefault
definedeletedesc
describedescriptordirectory
disabledisplaydistinct
dodropelse
enableendend-exec
endiferaseescape
execexecuteexists
explainextractfetch
filefileexistsfilename
firstfloatflush
forforcefound
freefromfunction
getglobalgo
gotograntgroup
havingholdhost_stride_length
houriafidentified
ifdefifndefimmediate
inincludeindicator
indicator_stride_lengthinputinsert
integerinternal_lengthintersect
intervalintois
isopenistemporarylast
leadinglengthlevel
likelistload
loblocallock
longmaxmessage
minminusminute
modemonthname
national_characterncharnext
nextvalnoauditnot
notfoundnowaitnull
nullablenumbernvarchar2
octet_lengthofone
onlyopenoption
ororacleorder
outputoverlapsoverpunch
packagepartitionperform
precisionprepareprior
procedureputraw
readrefreference
releaserenamereplace
returnreturned_lengthreturned_octet_length
returningrevokerole
rollbackrowidrownum
savepointscalesecond
sectionselectset
somesqlsql-context
sql-cursorsqlerrorsqlwarning
startstatementstddev
stopstringsum
sysdatesysdbasysoper
tabletemporarythreads
timetimestamptimezone_hour
timezone_minutetotools
trailingtransactiontrigger
trimtruncatetype
uidunionunique
unsigneduser_defined_type_nameuser_defined_type_name_length
user_defined_type_schemauser_defined_type_schema_lengthuser_defined_type_version
updateuseuser
usingvalidatevalue
valuesvarvarchar
varchar2variablesvariance
varnumvarrawview
wheneverwherewith
workwriteyear
zone--

Reserved Namespaces

Table B-1 contains a list of namespaces that are reserved by Oracle. The initial characters of subprogram names in Oracle libraries are restricted to the character strings in this list. Because of potential name conflicts, use subprogram names that do not begin with these characters.

For example, the Oracle Net Transparent Network Service functions all begin with the characters "NS," so avoid writing subprograms with names beginning with "NS."

Table B-1 Reserved Namespaces

NamespaceLibrary

XA

external functions for XA applications only

SQ

external SQLLIB functions used by Oracle Precompiler and SQL*Module applications

O, OCI

external OCI functions internal OCI functions

UPI, KP

function names from the Oracle UPI layer

NA

NC

ND

NL

NM

NR

NS

NT

NZ

OSN

TTC

Oracle Net Native services product

Oracle Net RPC project

Oracle Net Directory

Oracle Net Network Library layer

Oracle Net Net Management Project

Oracle Net Interchange

Oracle Net Transparent Network Service

Oracle Net Drivers

Oracle Net Security Service

Oracle Net V1

Oracle Net Two task

GEN, L, ORA

Core library functions

LI, LM, LX

function names from the Oracle Globalization Support layer

S

function names from system-dependent libraries


PKaVxQxPKFJOEBPS/partpage1.htmY Introduction and Concepts

Part I

Introduction and Concepts

Part I contains the following chapters:

PK#^YPKFJOEBPS/preface.htm Preface

Preface

This manual is a comprehensive user's guide and reference to the Oracle Pro*COBOL Precompiler. It shows you how to develop COBOL programs that use the database languages SQL and PL/SQL to access and manipulate Oracle data. See Oracle Database SQL Language Reference and PL/SQL User’s Guide and Reference for more information on SQL and PL/SQL.

This Preface contains these topics:

Intended Audience

The Pro*COBOL Programmer's Guide is intended for anyone developing new COBOL applications or converting existing applications to run in the Oracle environment. Written especially for programmers, this comprehensive treatment of Pro*COBOL will also be of value to systems analysts, project managers, and others interested in embedded SQL applications.

To use this manual effectively, you need a working knowledge of the following subjects:

Documentation Accessibility

Our goal is to make Oracle products, services, and supporting documentation accessible to all users, including users that are disabled. To that end, our documentation includes features that make information available to users of assistive technology. This documentation is available in HTML format, and contains markup to facilitate access by the disabled community. Accessibility standards will continue to evolve over time, and Oracle is actively engaged with other market-leading technology vendors to address technical obstacles so that our documentation can be accessible to all of our customers. For more information, visit the Oracle Accessibility Program Web site at http://www.oracle.com/accessibility/.

Accessibility of Code Examples in Documentation

Screen readers may not always correctly read the code examples in this document. The conventions for writing code require that closing braces should appear on an otherwise empty line; however, some screen readers may not always read a line of text that consists solely of a bracket or brace.

Accessibility of Links to External Web Sites in Documentation

This documentation may contain links to Web sites of other companies or organizations that Oracle does not own or control. Oracle neither evaluates nor makes any representations regarding the accessibility of these Web sites.

Deaf/Hard of Hearing Access to Oracle Support Services

To reach Oracle Support Services, use a telecommunications relay service (TRS) to call Oracle Support at 1.800.223.1711. An Oracle Support Services engineer will handle technical issues and provide customer support according to the Oracle service request process. Information about TRS is available at http://www.fcc.gov/cgb/consumerfacts/trs.html, and a list of phone numbers is available at http://www.fcc.gov/cgb/dro/trsphonebk.html.

Related Documents

For more information, see these Oracle resources:

Many of the examples in this book use the sample schemas of the seed database, which is installed by default when you install Oracle. Refer to Oracle Database Sample Schemas for information on how these schemas were created and how you can use them yourself.

Conventions

The following text conventions are used in this document:

ConventionMeaning
boldfaceBoldface type indicates graphical user interface elements associated with an action, or terms defined in text or the glossary.
italicItalic type indicates book titles, emphasis, or placeholder variables for which you supply particular values.
monospaceMonospace type indicates commands within a paragraph, URLs, code in examples, text that appears on the screen, or text that you enter.

PKYPKFJOEBPS/pco09dyn.htm Oracle Dynamic SQL

9 Oracle Dynamic SQL

This chapter shows you how to use dynamic SQL, an advanced programming technique that adds flexibility and functionality to your applications. After weighing the advantages and disadvantages of dynamic SQL, you learn four methods—from simple to complex—for writing programs that accept and process SQL statements "on the fly" at run time. You learn the requirements and limitations of each method and how to choose the right method for a given job.

Topics are:

Dynamic SQL

Most database applications do a specific job. For example, a simple program might prompt the user for an employee number, then update rows in the EMP and DEPT tables. In this case, you know the makeup of the UPDATE statement at precompile time. That is, you know which tables might be changed, the constraints defined for each table and column, which columns might be updated, and the datatype of each column.

However, some applications must accept (or build) and process a variety of SQL statements at run time. For example, a general-purpose report writer must build different SELECT statements for the various reports it generates. In this case, the statement's makeup is unknown until run time. Such statements can, and probably will, change from execution to execution. They are aptly called dynamic SQL statements.

Unlike static SQL statements, dynamic SQL statements are not embedded in your source program. Instead, they are stored in character strings input to or built by the program at run time. They can be entered interactively or read from a file.

Advantages and Disadvantages of Dynamic SQL

Host programs that accept and process dynamically defined SQL statements are more versatile than plain embedded SQL programs. Dynamic SQL statements can be built interactively with input from users having little or no knowledge of SQL.

For example, your program might simply prompt users for a search condition to be used in the WHERE clause of a SELECT, UPDATE, or DELETE statement. A more complex program might allow users to choose from menus listing SQL operations, table and view names, column names, and so on. Thus, dynamic SQL lets you write highly flexible applications.

However, some dynamic queries require complex coding, the use of special data structures, and more runtime processing. While you might not notice the added processing time, you might find the coding difficult unless you fully understand dynamic SQL concepts and methods.

When to Use Dynamic SQL

In practice, static SQL will meet nearly all your programming needs. Use dynamic SQL only if you need its open-ended flexibility. Its use is suggested when one or more of the following items is unknown at precompile time:

Requirements for Dynamic SQL Statements

To represent a dynamic SQL statement, a character string must contain the text of a valid DML or DDL SQL statement, but not contain the EXEC SQL clause, host-language delimiter or statement terminator.

In most cases, the character string can contain dummy host variables. They hold places in the SQL statement for actual host variables. Because dummy host variables are just place-holders, you do not declare them and can name them anything you like (hyphens are not allowed). For example, Oracle makes no distinction between the following two strings

'DELETE FROM EMP WHERE MGR = :MGRNUMBER AND JOB = :JOBTITLE'
'DELETE FROM EMP WHERE MGR = :M AND JOB = :J'

How Dynamic SQL Statements Are Processed

Typically, an application program prompts the user for the text of a SQL statement and the values of host variables used in the statement. Then Oracle parses the SQL statement. That is, Oracle examines the SQL statement to make sure it follows syntax rules and refers to valid database objects. Parsing also involves checking database access rights, reserving needed resources, and finding the optimal access path.

Next, Oracle binds the host variables to the SQL statement. That is, Oracle gets the addresses of the host variables so that it can read or write their values.

If the statement is a query, you define the SELECT variables and then Oracle FETCHes them until all rows are retrieved. The cursor is then closed.

Then Oracle executes the SQL statement. That is, Oracle does what the SQL statement requested, such as deleting rows from a table.

The SQL statement can be executed repeatedly using new values for the host variables.

Methods for Using Dynamic SQL

This section introduces the four methods you can use to define dynamic SQL statements. It briefly describes the capabilities and limitations of each method, then offers guidelines for choosing the right method. Later sections show you how to use the methods.

The four methods are increasingly general. That is, Method 2 encompasses Method 1, Method 3 encompasses Methods 1 and 2, and so on. However, each method is most useful for handling a certain kind of SQL statement, as Table 9-1 shows:

Table 9-1 Appropriate Method to Use

MethodKind of SQL Statement

1

Non-query without input host variables.

2

Non-query with known number of input host variables.

3

Query with known number of select-list items and input host variables.

4

Query with unknown number of select-list items or input host variables.


The term select-list item includes column names and expressions.

Method 1

This method lets your program accept or build a dynamic SQL statement, then immediately execute it using the EXECUTE IMMEDIATE command. The SQL statement must not be a query (SELECT statement) and must not contain any place-holders for input host variables. For example, the following host strings qualify:

'DELETE FROM EMP WHERE DEPTNO = 20'

'GRANT SELECT ON EMP TO SCOTT'

With Method 1, the SQL statement is parsed every time it is executed (regardless of whether you have set HOLD_CURSOR=YES).

Method 2

This method lets your program accept or build a dynamic SQL statement, then process it using the PREPARE and EXECUTE commands. The SQL statement must not be a query. The number of place-holders for input host variables and the datatypes of the input host variables must be known at precompile time. For example, the following host strings fall into this category:

'INSERT INTO EMP (ENAME, JOB) VALUES (:EMPNAME, :JOBTITLE)'
'DELETE FROM EMP WHERE EMPNO = :EMPNUMBER'

With Method 2, the SQL statement can be parsed just once by calling PREPARE once, and executed many times with different values for the host variables. This is not true when RELEASE_CURSOR=YES is also specified, because the statement has to be prepared again before each execution.


Note:

SQL data definition statements such as CREATE are executed once the PREPARE is completed.

Method 3

This method lets your program accept or build a dynamic query then process it using the PREPARE command with the DECLARE, OPEN, FETCH, and CLOSE cursor commands. The number of select-list items, the number of place-holders for input host variables, and the datatypes of the input host variables must be known at precompile time. For example, the following host strings qualify:

'SELECT DEPTNO, MIN(SAL), MAX(SAL) FROM EMP GROUP BY DEPTNO'
'SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO = :DEPTNUMBER'

Method 4

This method lets your program accept or build a dynamic SQL statement, then process it using descriptors (discussed in "Using Oracle Method 4"). The number of select-list items, the number of place-holders for input host variables, and the datatypes of the input host variables can be unknown until run time. For example, the following host strings fall into this category:

'INSERT INTO EMP (unknown) VALUES (unknown)'

'SELECT unknown FROM EMP WHERE DEPTNO = 20'

Method 4 is required for dynamic SQL statements that contain an unknown number of select-list items or input host variables.

Guidelines

With all four methods, you must store the dynamic SQL statement in a character string, which must be a host variable or quoted literal. When you store the SQL statement in the string, omit the keywords EXEC SQL and the statement terminator.

With Methods 2 and 3, the number of place-holders for input host variables and the datatypes of the input host variables must be known at precompile time.

Each succeeding method imposes fewer constraints on your application, but is more difficult to code. As a rule, use the simplest method you can. However, if a dynamic SQL statement will be executed repeatedly by Method 1, use Method 2 instead to avoid re-parsing for each execution.

Method 4 provides maximum flexibility, but requires complex coding and a full understanding of dynamic SQL concepts. In general, use Method 4 only if you cannot use Methods 1, 2, or 3.

The decision logic in Figure 9-1, "Choosing the Right Method", will help you choose the correct method.

Avoiding Common Errors

If you use a character array to store the dynamic SQL statement, blank-pad the array before storing the SQL statement. That way, you clear extraneous characters. This is especially important when you reuse the array for different SQL statements. As a rule, always initialize (or re-initialize) the host string before storing the SQL statement.

Do not null-terminate the host string. Oracle does not recognize the null terminator as an end-of-string marker. Instead, Oracle treats it as part of the SQL statement.

If you use a VARCHAR variable to store the dynamic SQL statement, make sure the length of the VARCHAR is set (or reset) correctly before you execute the PREPARE or EXECUTE IMMEDIATE statement.

EXECUTE resets the SQLWARN warning flags in the SQLCA. So, to catch mistakes such as an unconditional update (caused by omitting a WHERE clause), check the SQLWARN flags after executing the PREPARE statement but before executing the EXECUTE statement.

Figure 9-1 shows how to choose the right method.

Figure 9-1 Choosing the Right Method

Choosing the Right Method

Using Method 1

The simplest kind of dynamic SQL statement results only in "success" or "failure" and uses no host variables. Some examples follow:

'DELETE FROM table_name WHERE column_name = constant'
'CREATE TABLE table_name ...'
'DROP INDEX index_name'
'UPDATE table_name SET column_name = constant'
'GRANT SELECT ON table_name TO username'

The EXECUTE IMMEDIATE Statement

Method 1 parses, then immediately executes the SQL statement using the EXECUTE IMMEDIATE command. The command is followed by a character string (host variable or literal) containing the SQL statement to be executed, which cannot be a query.

The syntax of the EXECUTE IMMEDIATE statement follows:

EXEC SQL EXECUTE IMMEDIATE { :HOST-STRING | STRING-LITERAL }END-EXEC.

In the following example, you use the host variable SQL-STMT to store SQL statements input by the user:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
     ... 
 01   SQL-STMT  PIC X(120);
      EXEC SQL END DECLARE SECTION END-EXEC.
     ...
 LOOP.
     DISPLAY 'Enter SQL statement: ' WITH NO ADVANCING.
     ACCEPT SQL-STMT END-EXEC.
* --  sql_stmt now contains the text of a SQL statement
     EXEC SQL EXECUTE IMMEDIATE :SQL-STMT END-EXEC.
 NEXT.
     ...

Because EXECUTE IMMEDIATE parses the input SQL statement before every execution, Method 1 is best for statements that are executed only once. Data definition statements usually fall into this category.

An Example

The following fragment of a program prompts the user for a search condition to be used in the WHERE clause of an UPDATE statement, then executes the statement using Method 1:

     ...
*    THE RELEASE_CURSOR=YES OPTION INSTRUCTS PRO*COBOL TO
*    RELEASE IMPLICIT CURSORS ASSOCIATED WITH EMBEDDED SQL
*    STATEMENTS.  THIS ENSURES THAT Oracle DOES NOT KEEP PARSE
*    LOCKS ON TABLES, SO THAT SUBSEQUENT DATA MANIPULATION
*    OPERATIONS ON THOSE TABLES DO NOT RESULT IN PARSE-LOCK
*    ERRORS.
 
     EXEC ORACLE OPTION (RELEASE_CURSOR=YES) END-EXEC.
 
*   
     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
 01  USERNAME  PIC X(10) VALUE "SCOTT".
 01  PASSWD    PIC X(10) VALUE "TIGER".
 01  DYNSTMT   PIC X(80).
     EXEC SQL END DECLARE SECTION END-EXEC.
 01  UPDATESTMT PIC X(40).
 01  SEARCH-COND PIC X(40).
     ...
     DISPLAY "ENTER A SEARCH CONDITION FOR STATEMENT:".
     MOVE "UPDATE EMP SET COMM = 500 WHERE " TO UPDATESTMT.
     DISPLAY UPDATESTMT.
     ACCEPT SEARCH-COND.
*    Concatenate SEARCH-COND to UPDATESTMT and store result 
*    in DYNSTMT.
     STRING UPDATESTMT DELIMITED BY SIZE 
         SEARCH-COND DELIMITED BY SIZE INTO DYNSTMT.
     EXEC SQL EXECUTE IMMEDIATE :DYNSTMT END-EXEC.

Sample Program 6: Dynamic SQL Method 1

This program uses dynamic SQL Method 1 to create a table, insert a row, commit the insert, then drop the table.

      *****************************************************************
      * Sample Program 6:  Dynamic SQL Method 1                       *
      *                                                               *
      * This program uses dynamic SQL Method 1 to create a table,     *
      * insert a row, commit the insert, then drop the table.         *
      *****************************************************************
      
       IDENTIFICATION DIVISION.
       PROGRAM-ID.  DYNSQL1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

      *    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE
      *    THROUGH WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS
      *    INFORMATION AVAILABLE TO THE PROGRAM.

           EXEC SQL INCLUDE SQLCA END-EXEC.

      *    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE
      *    THROUGH WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS
      *    INFORMATION AVAILABLE TO THE PROGRAM.

           EXEC SQL INCLUDE ORACA END-EXEC.

      *    THE OPTION ORACA=YES MUST BE SPECIFIED TO ENABLE USE OF
      *    THE ORACA.

           EXEC ORACLE OPTION (ORACA=YES) END-EXEC.

      *    THE RELEASE_CURSOR=YES OPTION INSTRUCTS PRO*COBOL TO
      *    RELEASE IMPLICIT CURSORS ASSOCIATED WITH EMBEDDED SQL
      *    STATEMENTS.  THIS ENSURES THAT ORACLE DOES NOT KEEP PARSE
      *    LOCKS ON TABLES, SO THAT SUBSEQUENT DATA MANIPULATION
      *    OPERATIONS ON THOSE TABLES DO NOT RESULT IN PARSE-LOCK
      *    ERRORS.

           EXEC ORACLE OPTION (RELEASE_CURSOR=YES) END-EXEC.

           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME  PIC X(10) VALUE "SCOTT".
       01  PASSWD    PIC X(10) VALUE "TIGER".
       01  DYNSTMT   PIC X(80) VARYING.
           EXEC SQL END DECLARE SECTION END-EXEC.

      *    DECLARE VARIABLES NEEDED TO DISPLAY COMPUTATIONALS.
       01  ORASLNRD  PIC 9(9).

       PROCEDURE DIVISION.

       MAIN.

      *    BRANCH TO PARAGRAPH SQLERROR IF AN ORACLE ERROR OCCURS.
           EXEC SQL WHENEVER SQLERROR GOTO SQLERROR END-EXEC.

      *    SAVE TEXT OF CURRENT SQL STATEMENT IN THE ORACA IF AN ERROR
      *    OCCURS.
           MOVE 1 TO ORASTXTF.

      *    CONNECT TO ORACLE.
           EXEC SQL
               CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
           DISPLAY " ".
           DISPLAY "CONNECTED TO ORACLE AS USER:  " WITH NO ADVANCING.
           DISPLAY USERNAME.
           DISPLAY " ".

      *    EXECUTE A STRING LITERAL TO CREATE THE TABLE.  HERE, YOU
      *    GENERALLY USE A STRING VARIABLE INSTEAD OF A LITERAL, AS IS
      *    DONE LATER IN THIS PROGRAM.  BUT, YOU CAN USE A LITERAL IF
      *    YOU WISH.
           DISPLAY "CREATE TABLE DYN1 (COL1 CHAR(4))".
           DISPLAY " ".
           EXEC SQL EXECUTE IMMEDIATE
               "CREATE TABLE DYN1 (COL1 CHAR(4))"
           END-EXEC.

      *    ASSIGN A SQL STATEMENT TO THE VARYING STRING DYNSTMT.
      *    SET THE -LEN PART TO THE LENGTH OF THE -ARR PART.
           MOVE "INSERT INTO DYN1 VALUES ('TEST')" TO DYNSTMT-ARR. 
           MOVE 36 TO DYNSTMT-LEN.
           DISPLAY DYNSTMT-ARR.
           DISPLAY " ".

      *    EXECUTE DYNSTMT TO INSERT A ROW.  THE SQL STATEMENT IS A
      *    STRING VARIABLE WHOSE CONTENTS THE PROGRAM MAY DETERMINE
      *    AT RUN TIME.
           EXEC SQL EXECUTE IMMEDIATE :DYNSTMT END-EXEC.

      *    COMMIT THE INSERT.
           EXEC SQL COMMIT WORK END-EXEC.

      *    CHANGE DYNSTMT AND EXECUTE IT TO DROP THE TABLE.
           MOVE "DROP TABLE DYN1" TO DYNSTMT-ARR.
           MOVE 19 TO DYNSTMT-LEN.
           DISPLAY DYNSTMT-ARR.
           DISPLAY " ".
           EXEC SQL EXECUTE IMMEDIATE :DYNSTMT END-EXEC.

      *    COMMIT ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
           EXEC SQL COMMIT RELEASE END-EXEC.
           DISPLAY "HAVE A GOOD DAY!".
           DISPLAY " ".
           STOP RUN.

       SQLERROR.

      *    ORACLE ERROR HANDLER.  PRINT DIAGNOSTIC TEXT CONTAINING
      *    ERROR MESSAGE, CURRENT SQL STATEMENT, AND LOCATION OF ERROR.
           DISPLAY SQLERRMC.
           DISPLAY "IN ", ORASTXTC.
           MOVE ORASLNR TO ORASLNRD.
           DISPLAY "ON LINE ", ORASLNRD, " OF ", ORASFNMC.

      *    DISABLE ORACLE ERROR CHECKING TO AVOID AN INFINITE LOOP
      *    SHOULD ANOTHER ERROR OCCUR WITHIN THIS PARAGRAPH.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.

      *    ROLL BACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
           EXEC SQL ROLLBACK RELEASE END-EXEC.
           STOP RUN.

Using Method 2

What Method 1 does in one step, Method 2 does in two. The dynamic SQL statement, which cannot be a query, is first prepared (named and parsed), then executed.

With Method 2, the SQL statement can contain place-holders for input host variables and indicator variables. You can PREPARE the SQL statement once, then EXECUTE it repeatedly using different values of the host variables. Also, if you have not specified MODE=ANSI, you need not re-prepare the SQL statement after a COMMIT or ROLLBACK (unless you log off and reconnect).

The syntax of the PREPARE statement follows:

     EXEC SQL PREPARE STATEMENT-NAME
         FROM { :HOST-STRING | STRING-LITERAL }
     END-EXEC.

PREPARE parses the SQL statement and gives it a name.

STATEMENT-NAME is an identifier used by the precompiler, not a host or program variable, and should not be declared in a COBOL statement. It simply designates the prepared statement you want to EXECUTE.

The syntax of the EXECUTE statement is

     EXEC SQL
         EXECUTE STATEMENT-NAME [USING HOST-VARIABLE-LIST]
     END-EXEC.

where HOST-VARIABLE-LIST stands for the following syntax:

:HOST-VAR1[:INDICATOR1] [, HOST-VAR2[:INDICATOR2], ...]

EXECUTE executes the parsed SQL statement, using the values supplied for each input host variable. In the following example, the input SQL statement contains the place-holder n:

     EXEC SQL BEGIN DECLARE SECTION END-EXEC.
     ... 
 01  EMP-NUMBER   PIC S9(4) COMP VALUE ZERO.
     ...
 01  DELETE-STMT   PIC X(120) VALUE SPACES.
     ...
     EXEC SQL END DECLARE SECTION END-EXEC. 
 01  WHERE-STMT    PIC X(40).
 01  SEARCH-COND   PIC X(40). 
     ... 
     MOVE 'DELETE FROM EMP WHERE EMPNO = :N AND ' TO WHERE-STMT.
     DISPLAY 'Complete this statement's search condition:'.
     DISPLAY WHERE-STMT.
     ACCEPT SEARCH-COND.
*    Concatenate SEARCH-COND to WHERE-STMT and store in DELETE-STMT
     STRING WHERE-STMT DELIMITED BY SIZE
         SEARCH-COND DELIMITED BY SIZE INTO
         DELETE-STMT. 
     EXEC SQL PREPARE SQLSTMT FROM :DELETE-STMT END-EXEC.
 LOOP.
     DISPLAY 'Enter employee number: ' WITH NO ADVANCING.
     ACCEPT EMP-NUMBER.
     IF EMP-NUMBER = 0
        GO TO NEXT.
     EXEC SQL EXECUTE SQLSTMT USING :EMP-NUMBER END-EXEC.
 NEXT.

With Method 2, you must know the datatypes of input host variables at precompile time. In the last example, EMP-NUMBER was declared as type PIC S9(4) COMP. It could also have been declared as type PIC X(4) or COMP-1, because Oracle supports all these datatype conversions to the NUMBER internal datatype.

The USING Clause

When the SQL statement EXECUTE is completed, input host variables in the USING clause replace corresponding place-holders in the prepared dynamic SQL statement.

Every place-holder in the dynamic SQL statement after PREPARE must correspond to a host variable in the USING clause. So, if the same place-holder appears two or more times in the statement after PREPARE, each appearance must correspond to a host variable in the USING clause. If one of the host variables in the USING clause is an array, all must be arrays. Otherwise, only one record is then processed.

The names of the place-holders need not match the names of the host variables. However, the order of the place-holders in the dynamic SQL statement after PREPARE must match the order of corresponding host variables in the USING clause.

To specify NULLs, you can associate indicator variables with host variables in the USING clause. For more information, see "Using Indicator Variables".

Sample Program 7: Dynamic SQL Method 2

This program uses dynamic SQL Method 2 to insert two rows into the EMP table and then delete them.

      *****************************************************************
      * Sample Program 7:  Dynamic SQL Method 2                       *
      *                                                               *
      * This program uses dynamic SQL Method 2 to insert two rows     *
      * into the EMP table, then delete them.                         *
      *****************************************************************
      
       IDENTIFICATION DIVISION.
       PROGRAM-ID.  DYNSQL2.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

      *    INCLUDE THE SQL COMMUNICATIONS AREA, A STRUCTURE THROUGH
      *    WHICH ORACLE MAKES RUNTIME STATUS INFORMATION (SUCH AS ERROR
      *    CODES, WARNING FLAGS, AND DIAGNOSTIC TEXT) AVAILABLE TO THE
      *    PROGRAM.
           EXEC SQL INCLUDE SQLCA END-EXEC.

      *    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE THROUGH
      *    WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS INFORMATION
      *    AVAILABLE TO THE PROGRAM.
           EXEC SQL INCLUDE ORACA END-EXEC.

      *    THE OPTION ORACA=YES MUST BE SPECIFIED TO ENABLE USE OF
      *    THE ORACA.
           EXEC ORACLE OPTION (ORACA=YES) END-EXEC.

           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME  PIC X(10) VALUE "SCOTT".
       01  PASSWD    PIC X(10) VALUE "TIGER".
       01  DYNSTMT   PIC X(80) VARYING.
       01  EMPNO     PIC S9(4) COMPUTATIONAL VALUE 1234.
       01  DEPTNO1   PIC S9(4) COMPUTATIONAL VALUE 10.
       01  DEPTNO2   PIC S9(4) COMPUTATIONAL VALUE 20.
           EXEC SQL END DECLARE SECTION END-EXEC.

      *    DECLARE VARIABLES NEEDED TO DISPLAY COMPUTATIONALS.
       01  EMPNOD    PIC 9(4).
       01  DEPTNO1D  PIC 9(2).
       01  DEPTNO2D  PIC 9(2).
       01  ORASLNRD  PIC 9(9).

       PROCEDURE DIVISION.
       MAIN.

      *    BRANCH TO PARAGRAPH SQLERROR IF AN ORACLE ERROR OCCURS.
           EXEC SQL WHENEVER SQLERROR GOTO SQLERROR END-EXEC.

      *    SAVE TEXT OF CURRENT SQL STATEMENT IN THE ORACA IF AN ERROR
      *    OCCURS.
           MOVE 1 TO ORASTXTF.

      *    CONNECT TO ORACLE.
           EXEC SQL
               CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
           DISPLAY " ".
           DISPLAY "CONNECTED TO ORACLE.".
           DISPLAY " ".

      *    ASSIGN A SQL STATEMENT TO THE VARYING STRING DYNSTMT.  BOTH
      *    THE ARRAY AND THE LENGTH PARTS MUST BE SET PROPERLY.  NOTE
      *    THAT THE STATEMENT CONTAINS TWO HOST VARIABLE PLACEHOLDERS,
      *    V1 AND V2, FOR WHICH ACTUAL INPUT HOST VARIABLES MUST BE
      *    SUPPLIED AT EXECUTE TIME.
           MOVE "INSERT INTO EMP (EMPNO, DEPTNO) VALUES (:V1, :V2)"
               TO DYNSTMT-ARR.
           MOVE 49 TO DYNSTMT-LEN.

      *    DISPLAY THE SQL STATEMENT AND ITS CURRENT INPUT HOST
      *    VARIABLES.
           DISPLAY DYNSTMT-ARR.
           MOVE EMPNO TO EMPNOD.
           MOVE DEPTNO1 TO DEPTNO1D.
           DISPLAY "    V1 = ", EMPNOD, "    V2 = ", DEPTNO1D.

      *    THE PREPARE STATEMENT ASSOCIATES A STATEMENT NAME WITH A
      *    STRING CONTAINING A SQL STATEMENT.  THE STATEMENT NAME IS
      *    A SQL IDENTIFIER, NOT A HOST VARIABLE, AND THEREFORE DOES
      *    NOT APPEAR IN THE DECLARE SECTION.

      *    A SINGLE STATEMENT NAME MAY BE PREPARED MORE THAN ONCE,
      *    OPTIONALLY FROM A DIFFERENT STRING VARIABLE.
           EXEC SQL PREPARE S FROM :DYNSTMT END-EXEC.

      *    THE EXECUTE STATEMENT EXECUTES A PREPARED SQL STATEMENT
      *    USING THE SPECIFIED INPUT HOST VARIABLES, WHICH ARE
      *    SUBSTITUTED POSITIONALLY FOR PLACEHOLDERS IN THE PREPARED
      *    STATEMENT.  FOR EACH OCCURRENCE OF A PLACEHOLDER IN THE
      *    STATEMENT THERE MUST BE A VARIABLE IN THE USING CLAUSE.
      *    THAT IS, IF A PLACEHOLDER OCCURS MULTIPLE TIMES IN THE
      *    STATEMENT, THE CORRESPONDING VARIABLE MUST APPEAR
      *    MULTIPLE TIMES IN THE USING CLAUSE.  THE USING CLAUSE MAY 
      *    BE OMITTED ONLY IF THE STATEMENT CONTAINS NO PLACEHOLDERS.
      *    A SINGLE PREPARED STATEMENT MAY BE EXECUTED MORE THAN ONCE,
      *    OPTIONALLY USING DIFFERENT INPUT HOST VARIABLES.
           EXEC SQL EXECUTE S USING :EMPNO, :DEPTNO1 END-EXEC.

      *    INCREMENT EMPNO AND DISPLAY NEW INPUT HOST VARIABLES.
           ADD 1 TO EMPNO.
           MOVE EMPNO TO EMPNOD.
           MOVE DEPTNO2 TO DEPTNO2D.
           DISPLAY "    V1 = ", EMPNOD, "    V2 = ", DEPTNO2D.

      *    REEXECUTE S TO INSERT THE NEW VALUE OF EMPNO AND A
      *    DIFFERENT INPUT HOST VARIABLE, DEPTNO2.  A REPREPARE IS NOT
      *    NECESSARY.
           EXEC SQL EXECUTE S USING :EMPNO, :DEPTNO2 END-EXEC.

      *    ASSIGN A NEW VALUE TO DYNSTMT.
           MOVE "DELETE FROM EMP WHERE DEPTNO = :V1 OR DEPTNO = :V2"
               TO DYNSTMT-ARR.
           MOVE 50 TO DYNSTMT-LEN.

      *    DISPLAY THE NEW SQL STATEMENT AND ITS CURRENT INPUT HOST
      *    VARIABLES.
           DISPLAY DYNSTMT-ARR.
           DISPLAY "    V1 = ", DEPTNO1D, "      V2 = ", DEPTNO2D.

      *    REPREPARE S FROM THE NEW DYNSTMT. 
           EXEC SQL PREPARE S FROM :DYNSTMT END-EXEC.

      *    EXECUTE THE NEW S TO DELETE THE TWO ROWS PREVIOUSLY
      *    INSERTED.
           EXEC SQL EXECUTE S USING :DEPTNO1, :DEPTNO2 END-EXEC.

      *    ROLLBACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
           EXEC SQL ROLLBACK RELEASE END-EXEC.
           DISPLAY " ".
           DISPLAY "HAVE A GOOD DAY!".
           DISPLAY " ".
           STOP RUN.

        SQLERROR.
      *    ORACLE ERROR HANDLER.  PRINT DIAGNOSTIC TEXT CONTAINING
      *    ERROR MESSAGE, CURRENT SQL STATEMENT, AND LOCATION OF ERROR.
           DISPLAY SQLERRMC.
           DISPLAY "IN ", ORASTXTC.
           MOVE ORASLNR TO ORASLNRD.
           DISPLAY "ON LINE ", ORASLNRD, " OF ", ORASFNMC.

      *    DISABLE ORACLE ERROR CHECKING TO AVOID AN INFINITE LOOP
      *    SHOULD ANOTHER ERROR OCCUR WITHIN THIS PARAGRAPH.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.

      *    ROLL BACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
           EXEC SQL ROLLBACK RELEASE END-EXEC.
           STOP RUN.

Using Method 3

Method 3 is similar to Method 2 but combines the PREPARE statement with the statements needed to define and manipulate a cursor. This allows your program to accept and process queries. In fact, if the dynamic SQL statement is a query, you must use Method 3 or 4.

For Method 3, the number of columns in the query select list and the number of place-holders for input host variables must be known at precompile time. However, the names of database objects such as tables and columns need not be specified until run time (they cannot duplicate the names of host variables). Clauses that limit, group, and sort query results (such as WHERE, GROUP BY, and ORDER BY) can also be specified at run time.

With Method 3, you use the following sequence of embedded SQL statements:

     EXEC SQL 
         PREPARE STATEMENTNAME FROM { :HOST-STRING | STRING-LITERAL }
     END-EXEC. 
     EXEC SQL DECLARE CURSORNAME CURSOR FOR STATEMENTNAME END-EXEC.
     EXEC SQL OPEN CURSORNAME [USING HOST-VARIABLE-LIST] END-EXEC.
     EXEC SQL FETCH CURSORNAME INTO HOST-VARIABLE-LIST END-EXEC.
     EXEC SQL CLOSE CURSORNAME END-EXEC.

Now let us look at what each statement does.

PREPARE

The PREPARE statement parses the dynamic SQL statement and gives it a name. In the following example, PREPARE parses the query stored in the character string SELECT-STMT and gives it the name SQLSTMT:

     MOVE 'SELECT MGR, JOB FROM EMP WHERE SAL < :SALARY'
         TO SELECT-STMT.
     EXEC SQL PREPARE SQLSTMT FROM :SELECT-STMT END-EXEC.

Commonly, the query WHERE clause is input from a terminal at run time or is generated by the application.

The identifier SQLSTMT is not a host or program variable, but must be unique. It designates a particular dynamic SQL statement.

The following statement is correct also:

     EXEC SQL 
         PREPARE SQLSTMT FROM 'SELECT MGR, JOB FROM EMP WHERE SAL < :SALARY' 
     END-EXEC.

The following PREPARE statement, which uses the '%' wildcard, is also correct:

     MOVE "SELECT ENAME FROM TEST WHERE ENAME LIKE 'SMIT%'" TO MY-STMT.
     EXEC SQL 
         PREPARE S FROM MY-STMT
     END-EXEC.

DECLARE

The DECLARE statement defines a cursor by giving it a name and associating it with a specific query. The cursor declaration is local to its precompilation unit. Continuing our example, DECLARE defines a cursor named EMPCURSOR and associates it with SQLSTMT, as follows:

     EXEC SQL DECLARE EMPCURSOR CURSOR FOR SQLSTMT END-EXEC.

The identifiers SQLSTMT and EMPCURSOR are not host or program variables, but must be unique. If you declare two cursors using the same statement name, Pro*COBOL considers the two cursor names synonymous. For example, if you execute the statements

     EXEC SQL PREPARE SQLSTMT FROM :SELECT-STMT END-EXEC.
     EXEC SQL DECLARE EMPCURSOR FOR SQLSTMT END-EXEC.
     EXEC SQL PREPARE SQLSTMT FROM :DELETE-STMT END-EXEC.
     EXEC SQL DECLARE DEPCURSOR FOR SQLSTMT END-EXEC.

when you OPEN EMPCURSOR, you will process the dynamic SQL statement stored in DELETE-STMT, not the one stored in SELECT-STMT.

OPEN

The OPEN statement allocates a cursor, binds input host variables, and executes the query, identifying its active set. OPEN also positions the cursor on the first row in the active set and zeroes the rows-processed count kept by the third element of SQLERRD in the SQLCA. Input host variables in the USING clause replace corresponding place-holders in the PREPAREd dynamic SQL statement.

In our example, OPEN allocates EMPCURSOR and assigns the host variable SALARY to the WHERE clause, as follows:

     EXEC SQL OPEN EMPCURSOR USING :SALARY END-EXEC.

FETCH

The FETCH statement returns a row from the active set, assigns column values in the select list to corresponding host variables in the INTO clause, and advances the cursor to the next row. When no more rows are found, FETCH returns the "no data found" error code to SQLCODE in the SQLCA.

In our example, FETCH returns a row from the active set and assigns the values of columns MGR and JOB to host variables MGR-NUMBER and JOB-TITLE, as follows:

     EXEC SQL FETCH EMPCURSOR INTO :MGR-NUMBER,:JOB-TITLE END-EXEC.

Host tables can be used with Method 3.

CLOSE

The CLOSE statement disables the cursor. Once you CLOSE a cursor, you can no longer FETCH from it. In our example, the CLOSE statement disables EMPCURSOR, as follows:

     EXEC SQL CLOSE EMPCURSOR END-EXEC.

Sample Program 8: Dynamic SQL Method 3

This program uses dynamic SQL Method 3 to retrieve the names of all employees in a given department from the EMP table.

      *****************************************************************
      * Sample Program 8:  Dynamic SQL Method 3                       *
      *                                                               *
      * This program uses dynamic SQL Method 3 to retrieve the names  *
      * of all employees in a given department from the EMP table.    *
      *****************************************************************
      
       IDENTIFICATION DIVISION.
       PROGRAM-ID.  DYNSQL3.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

      *    INCLUDE THE SQL COMMUNICATIONS AREA, A STRUCTURE THROUGH
      *    WHICH ORACLE MAKES RUNTIME STATUS INFORMATION (SUCH AS ERROR
      *    CODES, WARNING FLAGS, AND DIAGNOSTIC TEXT) AVAILABLE TO THE
      *    PROGRAM.
           EXEC SQL INCLUDE SQLCA END-EXEC.

      *    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE THROUGH
      *    WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS INFORMATION
      *    AVAILABLE TO THE PROGRAM.
           EXEC SQL INCLUDE ORACA END-EXEC.

      *    THE ORACA=YES OPTION MUST BE SPECIFIED TO ENABLE USE OF
      *    THE ORACA.
           EXEC ORACLE OPTION (ORACA=YES) END-EXEC.

           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME  PIC X(10) VALUE "SCOTT".
       01  PASSWD    PIC X(10) VALUE "TIGER".
       01  DYNSTMT   PIC X(80) VARYING.
       01  ENAME     PIC X(10).
       01  DEPTNO    PIC S9999 COMPUTATIONAL VALUE 10.
           EXEC SQL END DECLARE SECTION END-EXEC.

      *    DECLARE VARIABLES NEEDED TO DISPLAY COMPUTATIONALS.
       01  DEPTNOD   PIC 9(2).
       01  ENAMED    PIC X(10).
       01  SQLERRD3  PIC 9(2).
       01  ORASLNRD  PIC 9(4).

       PROCEDURE DIVISION.
       MAIN.

      *    BRANCH TO PARAGRAPH SQLERROR IF AN ORACLE ERROR OCCURS.
           EXEC SQL WHENEVER SQLERROR GO TO SQLERROR END-EXEC.

      *    SAVE TEXT OF CURRENT SQL STATEMENT IN THE ORACA IF AN ERROR
      *    OCCURS.
           MOVE 1 TO ORASTXTF.

      *    CONNECT TO ORACLE.
           EXEC SQL
               CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
           DISPLAY " ".
           DISPLAY "CONNECTED TO ORACLE.".
           DISPLAY " ".

      *    ASSIGN A SQL QUERY TO THE VARYING STRING DYNSTMT.  BOTH THE
      *    ARRAY AND THE LENGTH PARTS MUST BE SET PROPERLY.  NOTE THAT
      *    THE STATEMENT CONTAINS ONE HOST VARIABLE PLACEHOLDER, V1,
      *    FOR WHICH AN ACTUAL INPUT HOST VARIABLE MUST BE SUPPLIED
      *    AT OPEN TIME.
           MOVE "SELECT ENAME FROM EMP WHERE DEPTNO = :V1"
               TO DYNSTMT-ARR.
           MOVE 40 TO DYNSTMT-LEN.

      *    DISPLAY THE SQL STATEMENT AND ITS CURRENT INPUT HOST
      *    VARIABLE.
           DISPLAY DYNSTMT-ARR.
           MOVE DEPTNO TO DEPTNOD.
           DISPLAY "    V1 = ", DEPTNOD.
           DISPLAY " ".
           DISPLAY "EMPLOYEE".
           DISPLAY "--------".

      *    THE PREPARE STATEMENT ASSOCIATES A STATEMENT NAME WITH A
      *    STRING CONTAINING A SELECT STATEMENT.  THE STATEMENT NAME,
      *    WHICH MUST BE UNIQUE, IS A SQL IDENTIFIER, NOT A HOST
      *    VARIABLE, AND SO DOES NOT APPEAR IN THE DECLARE SECTION.
           EXEC SQL PREPARE S FROM :DYNSTMT END-EXEC.

      *    THE DECLARE STATEMENT ASSOCIATES A CURSOR WITH A PREPARED
      *    STATEMENT.  THE CURSOR NAME, LIKE THE STATEMENT NAME, DOES
      *    NOT APPEAR IN THE DECLARE SECTION.
           EXEC SQL DECLARE C CURSOR FOR S END-EXEC.

      *    THE OPEN STATEMENT EVALUATES THE ACTIVE SET OF THE PREPARED
      *    QUERY USING THE SPECIFIED INPUT HOST VARIABLES, WHICH ARE
      *    SUBSTITUTED POSITIONALLY FOR PLACEHOLDERS IN THE PREPARED
      *    QUERY.  FOR EACH OCCURRENCE OF A PLACEHOLDER IN THE
      *    STATEMENT THERE MUST BE A VARIABLE IN THE USING CLAUSE.
      *    THAT IS, IF A PLACEHOLDER OCCURS MULTIPLE TIMES IN THE
      *    STATEMENT, THE CORRESPONDING VARIABLE MUST APPEAR MULTIPLE
      *    TIMES IN THE USING CLAUSE.  THE USING CLAUSE MAY BE
      *    OMITTED ONLY IF THE STATEMENT CONTAINS NO PLACEHOLDERS.
      *    OPEN PLACES THE CURSOR AT THE FIRST ROW OF THE ACTIVE SET
      *    IN PREPARATION FOR A FETCH.

      *    A SINGLE DECLARED CURSOR MAY BE OPENED MORE THAN ONCE,
      *    OPTIONALLY USING DIFFERENT INPUT HOST VARIABLES.
           EXEC SQL OPEN C USING :DEPTNO END-EXEC.

      *    BRANCH TO PARAGRAPH NOTFOUND WHEN ALL ROWS HAVE BEEN
      *    RETRIEVED.
           EXEC SQL WHENEVER NOT FOUND GO TO NOTFOUND END-EXEC.

       GETROWS.

      *    THE FETCH STATEMENT PLACES THE SELECT LIST OF THE CURRENT
      *    ROW INTO THE VARIABLES SPECIFIED BY THE INTO CLAUSE, THEN
      *    ADVANCES THE CURSOR TO THE NEXT ROW.  IF THERE ARE MORE
      *    SELECT-LIST FIELDS THAN OUTPUT HOST VARIABLES, THE EXTRA
      *    FIELDS ARE NOT RETURNED.  SPECIFYING MORE OUTPUT HOST
      *    VARIABLES THAN SELECT-LIST FIELDS RESULTS IN AN ORACLE ERROR.
           EXEC SQL FETCH C INTO :ENAME END-EXEC.
           MOVE ENAME TO ENAMED.
           DISPLAY ENAMED.

      *    LOOP UNTIL NOT FOUND CONDITION IS DETECTED.
           GO TO GETROWS.

       NOTFOUND.
           MOVE SQLERRD(3) TO SQLERRD3.
           DISPLAY " ".
           DISPLAY "QUERY RETURNED ", SQLERRD3, " ROW(S).".

      *    THE CLOSE STATEMENT RELEASES RESOURCES ASSOCIATED WITH THE
      *    CURSOR.
           EXEC SQL CLOSE C END-EXEC.

      *    COMMIT ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
           EXEC SQL COMMIT RELEASE END-EXEC.
           DISPLAY " ".
           DISPLAY "HAVE A GOOD DAY!".
           DISPLAY " ".
           STOP RUN.

       SQLERROR.

      *    ORACLE ERROR HANDLER.  PRINT DIAGNOSTIC TEXT CONTAINING
      *    ERROR MESSAGE, CURRENT SQL STATEMENT, AND LOCATION OF ERROR.
           DISPLAY SQLERRMC.
           DISPLAY "IN ", ORASTXTC.
           MOVE ORASLNR TO ORASLNRD.
           DISPLAY "ON LINE ", ORASLNRD, " OF ", ORASFNMC.

      *    DISABLE ORACLE ERROR CHECKING TO AVOID AN INFINITE LOOP
      *    SHOULD ANOTHER ERROR OCCUR WITHIN THIS PARAGRAPH.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.

      *    RELEASE RESOURCES ASSOCIATED WITH THE CURSOR.
           EXEC SQL CLOSE C END-EXEC.

      *    ROLL BACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
           EXEC SQL ROLLBACK RELEASE END-EXEC.
           STOP RUN.

Using Oracle Method 4

This section gives only an overview. For details, see Chapter 11, "Oracle Dynamic SQL: Method 4".

LOBs are not supported in Oracle Method 4. Use ANSI dynamic SQL for LOB applications and all other new applications.

There is a kind of dynamic SQL statement that your program cannot process using Method 3. When the number of select-list items or place-holders for input host variables is unknown until run time, your program must use a descriptor. A descriptor is an area of memory used by your program and Oracle to hold a complete description of the variables in a dynamic SQL statement.

Recall that for a multi-row query, you FETCH selected column values INTO a list of declared output host variables. If the select list is unknown, the host-variable list cannot be established at precompile time by the INTO clause. For example, you know the following query returns two column values:

     EXEC SQL
         SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO = :DEPT-NUMBER
     END-EXEC.

However, if you let the user define the select list, you might not know how many column values the query will return.

Need for the SQLDA

To process this kind of dynamic query, your program must issue the DESCRIBE SELECT LIST command and declare a data structure called the SQL Descriptor Area (SQLDA). Because it holds descriptions of columns in the query select list, this structure is also called a select descriptor.

Likewise, if a dynamic SQL statement contains an unknown number of place-holders for input host variables, the host-variable list cannot be established at precompile time by the USING clause.

To process the dynamic SQL statement, your program must issue the DESCRIBE BIND VARIABLES command and declare another kind of SQLDA called a bind descriptor to hold descriptions of the place-holders for the input host variables. (Input host variables are also called bind variables.)

If your program has more than one active SQL statement (it might have used OPEN for two or more cursors, for example), each statement must have its own SQLDAs statement. However, non-concurrent cursors can reuse SQLDAs. There is no set limit on the number of SQLDAs in a program.

The DESCRIBE Statement

DESCRIBE initializes a descriptor to hold descriptions of select-list items or input host variables.

If you supply a select descriptor, the DESCRIBE SELECT LIST statement examines each select-list item in a prepared dynamic query to determine its name, datatype, constraints, length, scale, and precision. It then stores this information in the select descriptor.

If you supply a bind descriptor, the DESCRIBE BIND VARIABLES statement examines each place-holder in a prepared dynamic SQL statement to determine its name, length, and the datatype of its associated input host variable. It then stores this information in the bind descriptor for your use. For example, you might use place-holder names to prompt the user for the values of input host variables.

SQLDA Contents

A SQLDA is a host-program data structure that holds descriptions of select-list items or input host variables.

Though SQLDAs differ among host languages, a generic select SQLDA contains the following information about a query select list:

  • Maximum number of columns that can be DESCRIBEd

  • Actual number of columns found by DESCRIBE

  • Addresses of buffers to store column values

  • Lengths of column values

  • Datatypes of column values

  • Addresses of indicator-variable values

  • Addresses of buffers to store column names

  • Sizes of buffers to store column names

  • Current lengths of column names

A generic bind SQLDA contains the following information about the input host variables in a SQL statement:

  • Maximum number of place-holders that can be DESCRIBEd

  • Actual number of place-holders found by DESCRIBE

  • Addresses of input host variables

  • Lengths of input host variables

  • Datatypes of input host variables

  • Addresses of indicator variables

  • Addresses of buffers to store place-holder names

  • Sizes of buffers to store place-holder names

  • Current lengths of place-holder names

  • Addresses of buffers to store indicator-variable names

  • Sizes of buffers to store indicator-variable names

  • Current lengths of indicator-variable names

Implementing Method 4

With Method 4, you generally use the following sequence of embedded SQL statements:

     EXEC SQL
         PREPARE STATEMENT-NAME
         FROM { :HOST-STRING | STRING-LITERAL }
     END-EXE
     EXEC SQL
         DECLARE CURSOR-NAME CURSOR FOR STATEMENT-NAME
     END-EXEC.
     EXEC SQL
         DESCRIBE BIND VARIABLES FOR STATEMENT-NAME
         INTO BIND-DESCRIPTOR-NAME
     END-EXEC.
     EXEC SQL 
         OPEN CURSOR-NAME
         [USING DESCRIPTOR BIND-DESCRIPTOR-NAME]
     END-EXEC.
     EXEC SQL
         DESCRIBE [SELECT LIST FOR] STATEMENT-NAME
         INTO SELECT-DESCRIPTOR-NAME
     END-EXEC.
     EXEC SQL 
         FETCH CURSOR-NAME
         USING DESCRIPTOR SELECT-DESCRIPTOR-NAME
     END-EXEC.
     EXEC SQL CLOSE CURSOR-NAME END-EXEC.

Select and bind descriptors need not work in tandem. If the number of columns in a query select list is known, but the number of place-holders for input host variables is unknown, you can use the Method 4 OPEN statement with the following Method 3 FETCH statement:

     EXEC SQL FETCH EMPCURSOR INTO :HOST-VARIABLE-LIST END-EXEC.

Conversely, if the number of place-holders for input host variables is known, but the number of columns in the select list is unknown, you can use the following Method 3 OPEN statement with the Method 4 FETCH statement:

     EXEC SQL OPEN CURSORNAME [USING HOST-VARIABLE-LIST] END-EXEC.

Note that EXECUTE can be used for non-queries with Method 4.

Using the DECLARE STATEMENT Statement

With Methods 2, 3, and 4, you might need to use the statement

      EXEC SQL [AT dbname] DECLARE statementname STATEMENT END-EXEC.

where dbname and statementname are identifiers used by Pro*COBOL, not host or program variables.

DECLARE STATEMENT declares the name of a dynamic SQL statement so that the statement can be referenced by PREPARE, EXECUTE, DECLARE CURSOR, and DESCRIBE. It is required if you want to execute the dynamic SQL statement at a nondefault database. An example using Method 2 follows:

     EXEC SQL AT remotedb DECLARE sqlstmt STATEMENT END-EXEC.
     EXEC SQL PREPARE sqltmt FROM :sqlstring END-EXEC.
     EXEC SQL EXECUTE sqlstmt END-EXEC.

In the example, remotedb tells Oracle where to EXECUTE the SQL statement.

With Methods 3 and 4, DECLARE STATEMENT is also required if the DECLARE CURSOR statement precedes the PREPARE statement, as shown in the following example:

     EXEC SQL DECLARE sqlstmt STATEMENT END-EXEC.
     EXEC SQL DECLARE empcursor CURSOR FOR sqlstmt END-EXEC.
     EXEC SQL PREPARE sqlstmt FROM :sqlstring END-EXEC.

The usual sequence of statements is

     EXEC SQL PREPARE sqlstmt FROM :sqlstring END-EXEC.
     EXEC SQL DECLARE empcursor CURSOR FOR sqlstmt END-EXEC.

Using Host Tables

Usage of host tables in static and dynamic SQL is similar. For example, to use input host tables with dynamic SQL Method 2, use the syntax

     EXEC SQL EXECUTE statementname USING :HOST-TABLE-LIST END-EXEC.

where HOST-TABLE-LIST contains one or more host tables. With Method 3, use the following syntax:

     OPEN cursorname USING :HOST-TABLE-LIST END-EXEC.

To use output host tables with Method 3, use the following syntax:

     FETCH cursorname INTO :HOST-TABLE-LIST END-EXEC.

With Method 4, you must use the optional FOR clause to tell Oracle the size of your input or output host table. To learn how this is done, see your host-language supplement.

Using PL/SQL

Pro*COBOL treats a PL/SQL block like a single SQL statement. So, like a SQL statement, a PL/SQL block can be stored in a string host variable or literal. When you store the PL/SQL block in the string, omit the keywords EXEC SQL EXECUTE, the keyword END-EXEC, and the statement terminator.

However, there are two differences in the way Pro*COBOL handles SQL and PL/SQL:

With Method 1

If the PL/SQL block contains no host variables, you can use Method 1 to EXECUTE the PL/SQL string in the usual way.

With Method 2

If the PL/SQL block contains a known number of input and output host variables, you can use Method 2 to PREPARE and EXECUTE the PL/SQL string in the usual way.

You must put all host variables in the USING clause. Once the PL/SQL string EXECUTE is completed, host variables in the USING clause replace corresponding place-holders in the string after PREPARE. Though Pro*COBOL treats all PL/SQL host variables as input host variables, values are assigned correctly. Input (program) values are assigned to input host variables, and output (column) values are assigned to output host variables.

Every place-holder in the PL/SQL string after PREPARE must correspond to a host variable in the USING clause. So, if the same place-holder appears two or more times in the PREPAREd string, each appearance must correspond to a host variable in the USING clause.

With Method 3

Methods 2 and 3 are the same except that Method 3 allows completion of a FETCH. Since you cannot FETCH from a PL/SQL block, use Method 2 instead.

With Method 4

If the PL/SQL block contains an unknown number of input or output host variables, you must use Method 4.

To use Method 4, you set up one bind descriptor for all the input and output host variables. Executing DESCRIBE BIND VARIABLES stores information about input and output host variables in the bind descriptor. Because you refer to all PL/SQL host variables with the methods associated with input host variables, executing DESCRIBE SELECT LIST has no effect.

The use of bind descriptors with Method 4 is detailed in your host-language supplement.

Note that in dynamic SQL Method 4, a host array cannot be bound to a PL/SQL procedure with a parameter of type "table."

Caution

Do not use ANSI-style Comments (- - ...) in a PL/SQL block that will be processed dynamically because end-of-line characters are ignored. As a result, ANSI-style Comments extend to the end of the block, not just to the end of a line. Instead, use C-style Comments (/* ... */).

Dynamic SQL Statement Caching

Statement caching refers to the feature that provides and manages a cache of statements for each session. In the server, it means that cursors are ready to be used without the need to parse the statement again. Statement caching can be enabled in the precompiler applications, which will help in the performance improvement of all applications that rely on the dynamic SQL statements. The performance improvement is achieved by removing the overhead of parsing the dynamic statements on reuse. The precompiler application user can obtain this performance improvement using a new command line option, stmt_cache (for the statement cache size), which will enable the statement caching of the dynamic statements. By enabling the new option, the statement cache will be created at session creation time. The caching is only applicable for the dynamic statements and the cursor cache for the static statements co-exists with the new feature.

The command line option stmt_cache can be given any value in the range of 0 to 65535. Statement caching is disabled by default (value 0). The stmt_cache option can be set to hold the anticipated number of distinct dynamic SQL statements in the application.

Example 9-1 Using the stmt_cache Option

This example demonstrates the use of the stmt_cache option. In this program, you insert rows into a table and select the inserted rows by using the cursor in the loop. When the stmt_cache option is used to precompile this program, the performance increases compared to a normal precom;pilation.

 *****************************************************************
      * stmtcache:                                                    *
      *                                                               *
      * NOTE:                                                         *
      * When this program is used to measure the performance with and *
      * without stmt_cache option, do the following changes in the    *
      * program,                                                      *
      * 1. Increase ROWSCNT to high value, say 10000.                 *
      * 2. Remove all the DISPLAY statements, usually which comsumes  *
      * significant portion of the total program execution time.      *
      *****************************************************************
 
       IDENTIFICATION DIVISION.
       PROGRAM-ID.  stmtcache.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
 
      * EMBEDDED COBOL (file "STMTCACHE.PCO")  
 
           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01  USERNAME          PIC X(10) VARYING.
       01  PASSWD            PIC X(10) VARYING.
       01  DYNSTMT   PIC X(100) VARYING.
       01  DYNSTMT2   PIC X(100) VARYING.
 
       01  ENAME PIC X(10).
       01  COMM PIC X(9).
 
           EXEC SQL END DECLARE SECTION END-EXEC.
 
       01  ROWSCNT  PIC 9(4) COMP VALUE 10. 
       01  LOOPNO PIC  9(4).
 
       01  STRINGFIELDS.
           02 STR PIC X(18) VARYING.
 
           EXEC SQL INCLUDE SQLCA END-EXEC.
 
       PROCEDURE DIVISION.
       BEGIN-PGM.
           EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.
 
           PERFORM LOGON.
 
           MOVE "INSERT INTO BONUS (ENAME, COMM) VALUES (:A,:B)"
                TO DYNSTMT-ARR.
           MOVE 53 TO DYNSTMT-LEN.
 
           DISPLAY "Inserts ", ROWSCNT, " rows into BONUS table.".
           PERFORM INSDATA VARYING LOOPNO FROM 1 BY 1 
                   UNTIL LOOPNO > ROWSCNT.
           
           DISPLAY " ".
 
           DISPLAY "Fetches the inserted rows from BONUS.".
           DISPLAY "  ENAME COMM".
 
           MOVE "SELECT ENAME, COMM FROM BONUS WHERE COMM=:A"
                TO DYNSTMT2-ARR.
           MOVE 43 TO DYNSTMT2-LEN.
 
           MOVE 1 TO LOOPNO.
 
      * Loops for preparing and fetching ROWSCNT number of times
       FETCHDATA.
      * Do the prepare in the loop so that the advantage of
      * stmt_caching is visible
           EXEC SQL PREPARE S2 FROM :DYNSTMT2 END-EXEC.
 
           EXEC SQL DECLARE C1 CURSOR FOR S2
           END-EXEC.
 
           EXEC SQL OPEN C1 USING :LOOPNO END-EXEC.
 
           EXEC SQL WHENEVER NOT FOUND GO TO NOTFOUND END-EXEC.
 
       GETROWS.
      * Close the cursor so that the reparsing is not required for
      * stmt_cache
           EXEC SQL FETCH C1 INTO :ENAME, :COMM
           END-EXEC.
           DISPLAY ENAME, COMM.
           GO TO GETROWS.
 
       NOTFOUND.
           EXEC SQL CLOSE C1 END-EXEC.
           COMPUTE LOOPNO = LOOPNO + 1.
 
           IF LOOPNO <= ROWSCNT THEN
             GO TO FETCHDATA
           END-IF.
 
           EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
           STOP RUN.
 
       LOGON.
           MOVE "scott" TO USERNAME-ARR.
           MOVE 5 TO USERNAME-LEN.
           MOVE "tiger" TO PASSWD-ARR.
           MOVE 5 TO PASSWD-LEN.
           EXEC SQL
               CONNECT :USERNAME IDENTIFIED BY :PASSWD
           END-EXEC.
 
      * Populates the host variable and insert into the table
       INSDATA.
           EXEC SQL PREPARE S1 FROM :DYNSTMT END-EXEC.
           MOVE " " TO STR.
           STRING "EMP_", LOOPNO INTO STR
           END-STRING.
           MOVE STR TO ENAME.
           MOVE LOOPNO TO COMM.
 
           EXEC SQL EXECUTE S1 USING :ENAME, :COMM END-EXEC.
 
      * HANDLES SQL ERROR CONDITIONS
       SQL-ERROR.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
           DISPLAY " ".
           DISPLAY "ORACLE ERROR DETECTED:".
           DISPLAY " ".
           DISPLAY SQLERRMC.
           EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
           STOP RUN.
PKZܢKPKFJOEBPS/img/lobdisab.gifoGIF87aP?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,P H*\ȰÇ'p " <0… :|1ĉ+Z1ƍ;RO@$X  <0… :|1ĉ+Z1ƍ;F̗/DŽѣG=zѣG=a|=zѣG=z#|̗ϣ|/|˗O`>yѣG=zѣG˗` g0|˗_>0@0 < ,h „ 2l!Ĉ'Rh"ƌ7Z̗O`|/_> __ G0_> ȑ#G9rȑ#G #/_A `>/߿| O|8`A <0… :|1ĉ+Z1F HA HP`|,X` ` ,Xp`| H*\ȰÇ#JHŋ3j `>8`A;xO@ DPB >QD-^ĘQ|1w0_(1ƍ7nܸqƍ7n˗o|moƍ7nܸqƍ7w1|˷a|6N̷qƍ7nܸqƍ滘a>  <8`>8`A&? 4xaB 6tbD)VxcF!̗O |'P`7p H'p "LX0,h „ 2l!Ĉ'Rh"ƌ a|!G0|7noƍ7nܸqƍ7̗a|C`>6n(1ƍ7nܸqƍ7nO@ /_#H`> O@ DPB 'p A H*\ȰÇ#JHŋ3.̗`|o`> 3OF5̗OF5jԨQF)w0߿|(߿| (0|O@ DPB s/_>:tСC:tСC:t!| ̗o`>ca>:t_>9tСC:tСC:tСC[`>Ca 8? O@ DPa>$ AO@ DPB >QD-^Ęq`.ca| ˗a|4j/_"ӨQF5jԨQF滘aC/|iH0_|ȨQF5jԨQF-w1|[/|4j5jԨQF5jo!|,h | ̗|+X` ,/_| +/_O@ DPB >QD-^Ęq`>̗`> '0_>/_> @/_>/_|˗O`(0_ 8p8`A&TaC!F8bE1fO#|k/|̗_˗/|̗_>/_/_|/_>70|5jԨQF5j1ƌ0_| _`/|70߿| G`>8`8`A&TaC!F8bE1fOF'p@ '0߿|O@_>/|(߿ ߿8`A'p "Lp!ÆB(q"Ŋ/b80Fk/|'0߿|˗o`|o`70_|˗/|廘OF5jԨQF!ӨQ`|̗o`>'0| ̗/߿|0@7p|7?8p  <0… :|1ĉ+Z1|50_>iԨ0|5jԨQF5j1F[/|('p ,h|"D? 4xaB 6tbD)VxcƁ4j/|˧Q|2ӨQF5jh`> 4xaB8| ,X` /_+X0_| ,X` /_ ,`A H8`> 4xaB 0 <0B H`>'p 8 A$XA%L0a„%/a„ &/_K80_| &La|&L/| &` &LH0| &L0a| ˗O`|%$0@ (`>8`AC!B ̇`>"D@ 'p "L0,h`70| ̗`| G`>(0̗/_>0@@/߿7080_̗o 8pO@ $`` /߿| ̇P`>'p "Lp!ÆB0|70|3`>'0߿|/|` 3O`| '0_|70|_g0_>̗O|$:g0| G0| ̗`[OD%J(Q| G0_| ̗`> O`/_/| g0|O`+o`| ̗O`|+` 3/| ̗_| 'qa80 7_˗/|o o| H*\ȰÇ#Fw0|W0߿|G0߿| '0߿| ̗_``>O`+o`>_| '0|˗`>˗/_̗`>30@ H|'P`/@ <0… :|1/_|`>80@ o`>˗/߿|0@@ o|O߿@ /߿'߿(08p@ ̗/@ _7P`0'p`'07p| /'p "Lp!ÆB(q"A 7_70 (? '0@'P_8P _(0 70| ̗/@ O@ H |O|_'p`>$XР|W0|70|O`|;80_| H*\ȰÇ#Jl_ /߿|W0_>'0_|70|G0_|3o``> O`>/| #_> ˗`/߿|G0D30|'p`| O'p|'p "Lp!ÆB(a> ˗/|/_|/|_|G0|/_|(? _˗o`|(0 /߿_7p O`807p`|/_? 4h0(R80| ;|(.G|)RH"E棘0|)&g0E3/|G1_> Q(1E)RH"E(&g0E G"Ł˧0_I̗/E(R"E)RH"|3"ń H|S/_|A̗/ņ(R"E)RH"|3"ń H|g0_| 0_|HQb>)RH"E ? 4x_>"D! C!Ḃ|O@(?(? 4x!|,h „ 'p "Lp!ÆB(q@$X 0 <0AO@ DPB$(0_| ,H`> O@ DPB >QD-^ĘQF=~RH%MDRJt-]SL5męSN=}TPEETRM>UTU^ŚUV]~VXe͞EVZmݾW\uśW^}X`… FXbƍ?,0 ;;PKp+PKFJOEBPS/img/pco81008.gifGIF87a?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳh'p "Lp!ÆB(q"Ŋ/b̘?7P`|̗/(0_| ̗/_˗o|(0_|˗o| /_|˗/@7P`|̗/8_>$XA .dC%NXE+OF5j̧QF5jԨQF̧QF5ӨQF8`A H*\ȰÇ#*'QD%J(1D%J(Q|I(QD%JOD%J(Qb>%J(QD"(QD%J/C O@$0@ 80_'p "Lp!Æ )O @ O'? ? H*\pa5lذaÆ 6lذ| '0_>/_>3/|O |G߿'p "Lp!Ä0@ '?/߿|'0_> o ,h „ 2\`|װaÆ 6lذaÆ̇0_> '0߿| W`>_/߿O <0… S0@(0_>˗/߿|'`> O@ DPB ̗O`6lذaÆ 6l`'0_>/|+/|o`>'p|? 4xaB &̷`>(0_>˗_|'0_|'P ,h „ 2\`|kذaÆ 6lذaà C/߿| '0߿| W0_>'0| ̗`>˗/_Æ 6l0_|'P࿁ O|˗_|'0_>`>8`A&T|;aÆ 6lذaÆ k`>70? @ |_ _ O@ DPB )O o O70? O@ DPB 70| 6lذaÆ 6lx0_Æ 6lذaÆ װaÆ 6lذaà ˗/| 6lذaÆ 6lx0_Æ 6lذaÆ װaÆ 6lذaÃװaÆ 6lذaÆ5lذaÆ 6lذ| 6lذaÆ 6 $ <0… :|1|I(QD%2'QD%J(QD%J(Q"|I(QD%2'QD%J(QD%J(Q"|%J(QD8`A&TaC!F8bE1fL <0… :|1b|%J(QD%J(QD%"'QD%J(1D%J(QD%J(QDI(QD%J'QD%Jh`> $ <0… :|1|I(QD%2'QD%Jh0_|%J(QD+OD%J(a>%J(QD"(QD%J/_|%J(QD I(QD%1D%J(Q$J(QD%S0@(? 0@ (? 4xaB 6|:tСC:LϡC:tC)7`>O '0_ /|'0_>$XA .d0_C6lذaÆ 6l` 6lذaÆ 64O!|߿ O|`>O? O@ DPB 5$aÆ 6lذaÆ kذaÆ 6lذaC'p`O '0_ /߿|˗O`| H*\Ȱa5lذaÆ 6lذ|5lذaÆ 6lذa O@˗/߿| ̗_|/_| H*\Ȱa5lذaÆ 6lذ|5lذaÆ 6lذa> ߿ @ O|`>8`A&TaСC:tСÄ sСC:tС|:tСC*p`>:tСC&СC:tСC:tСC:T|:tСC:LϡC:tСC9tСC:t0Á:tСC:t0C:tСCsСC:tPa>9tСC:t0a>:tСC"СC:tСB$X ,h „ 2l!Ĉ I(QD%J'QD%J(QD%J(Q"|I(QD%2'QD%J(QD%J(Q"|I(QD%2O@ DPB >QD-^Ę1!O@ DPB >q`>%J(QD%J(QD(QD%JOD%J(QD%J(QD$J(QD%(QD%J40 O@ DPB >Qa>%J(QD$J(QD 拘OD%J(Q|(? 4H0 G0| ;x` ;xA8`A&TaC!"W0_| +/b|'P߿8`> _>$XA +a/|˗/_>O`|˗`|˗`|/_|˗o`˗/߿|/_|70߿| ̗/| SPB *TPB ˗`>)/_|˗O`| ̗_|˗O`| ˗O`|/߿|o`| ̗_/_*Ta'p`?˗_>O` /|O`_>/_>/_>o`/߿|'0߿| 8p'p "Lp!ÆBD`_|˗O`>'0߿|o`| W`>/߿߿(0'0|/,h „̇0| g0߿|˗O`0@߿|_> '0߿| /|o`|70߿|O`> o`>$X| H*\ȰÇ+/b>/| '0? 70߿/߿? ̗_>o|o|70@ <0| #/|̗/߿| /|` '0_|'0|`|_ '0|'0_| ˧PB *TPB W0ƒ70߿|/|˗O`/|G0߿|'0| /| W0| *Tx0B ˗o`'P | ߿@O`>˗/@'P|8߿o`  <0… :|a"[0@ |o`߿?(߿|@ 0@߿'P`8`A&OB *TPB *TP`> *TPB *TPa>)TPB *TH0_| *T0B *TPB *TP| *TPB *TP| SPB *T`*T0a*TPB *TPB)TPB *TPB )"H0_|G`>߿|  O߿8`A&4O| Sx0ƒ̧`>)9|S/|'0_ ̗O`|/߿|:tСCp`>/|O` /|/|O__> 7_ '0O@ DP` Sx0ƒ̧`>)7O ,h „ 2lx0_0_|_0@70߿_'P`'0߿| _| O`/_'p "L(0_|) S/|/_|/|'0߿| *TPB ;O| _|˗O`>'0_| ̗O`> #_>o`| ̗O`|`> *)˗/߿|˗O`|'0_| *TPB 'PO@3X`>߿|߿/'P'߿8`>/߿o'p "L80̧`>)|a>|80|{(0C P`=a|>|Ç{(0Ç>|0|>$oa=|{(0C 0a>|Ç=Ç>|Æ +|{(0C P`=LÇ>||{Ç>|a {(0C P`=|{Ç>|`> $ <0… :|1|O@ DPB >t  <0… :|a"F1bĈ#*̷0_|E1_|E`#F1bD"1bĈ#F0|E1_|E1_ă"F1bĈ ˗/|E$` #0@ _ O@ '߿| Ḩ_>)/_/_|o`>'0| *T0̧`>)˗/| H W0_| Sx0ƒ̧`>)˗_O` o`_//߿|'0'0o`? 4xaB +O| Sx0ƒ̧`>)TH0B *TPB *T/|)))) *TPB ;OB S/ƒ̧`>) *TPB *TPa>)TPB *TPB ̧_>)%J(QD"(QD%J/_|E1_|E1_| (QD%J40 O@ DPB >Qa 'p "Lp!Æ:O@O@ DPB >QD-^Ę` 拘/b"拘/b0ӨQF8`A H*\ȰÇ#*̷0_|E1_|E'`>%J(QD"(QD%J/|E1_|E1D$J(QD 拘OD%J(Q| E1_|E1_| (QD%JW0_|%J(QD[/b"拘/b"h0D%J(b| 拘OD%J(Q|1_|E1_|I4OD%J(1_|I(QD%J`"拘/b"拘/b>$X| H*\ȰÇ+/b#F1bĈ W0_|E1_|E`#F1bD 拘/bĈ#F1| E1_|E1_|1bĈ#FD`"F1bĈ#*̷0_|E1_|E`#F1bD"1bĈ#F0|E1_|E1_ă"F1bĈ拘/bĈ#F1| E1_|E1_|1bĈ#Ft/b#F1bĈ W`> 4xaB 6t!,(0,h „ 2l!D"1bĈ#F0_|#F1bĈ1bĈ#Ft/b#F1bĈ 1bĈ#Fq`#F1bD H A$XA .dC(QD%JOD%J(`$J(QD%'QD%J(1D%J(Q|I(QD%JO"|˗a|A0_|˗/_C O@ !B"D!B"D|#!8`A&TaC!FTO|5̗O` 0_ '0_|S0@o'@ ̗O`| H*\p`|א` 6lذaÆ 6 ̗O`|/|'0_˗O`|/_Æ 6lx0| kذaÆ 6lذaà k80_C5$/_|kX0_|k(0_ S0@O? O '? /_'p "Lp!Âא` 6lذaÆ 6<`5|5O@$(0| 70_,X0_+X0_> ̗_|'0_> ̗O`W0_O@ DPBא` 6lذaÆ 6<`5O@$H0_| ,/_W`|,X0_ ,Xp`/|˗_|'0_/_̗_|8`A&T@ ߿| H| H*\ȰÇ#*'QD%J(1B (߿_(? O@ DPB 5$aÆ 6lذaÆ kذaÆ 6lذaC6lذaÆ 6lx0_C6lذaÆ 6l` 6lذaÆ 64aÆ 6lذaÆ5$aÆ 6lذaÆ kذaÆ 6lذaC6lذaÆ 6lx0_C6lذaÆ 6l`6lذaÆ 6l0_Æ 6lذaÆ 'p 8`A&TaC!FT`>%J(QD$J(QD 拘OD%J(Q|I(QD%2'QD%Jh0_|%J(QD(QD%JOD%J1_|拘OD%J(Q|%J(QDI(QD'0|I(QD%JOD%J(Qb>%J(Qb|1D%J(Q$J(QD%(QD%J̗`$J(QD%W0D%J(Q"|%J(Qć/߿O@O@ DPB >Qa$J(QD(QD%B̗/_>"(QD%J/_|%J(QD I(QD%1D%J(Q$J(QD%(QD%J4/b>%J(QDI(QD%J'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%'QD%J(1D%J(Q|I(QD%J`>%J(QD$J(QD 'p 8`A&TaC!FT`>%J(QD$J(QD%J(QD%JD`>%J(QD$J(QD%J(QD%JD`>%J(QD$J(QD 'p 8`A&TaC!FTOD%J(Qb>%J(QD"(QD%J/D%J(Q|%J(QD 拘OD%J(Q|%J(QDI(QD!˗`$J(QD%'QD%J(1D%J(Qb"(QD%J/_|%J(QD I(QD%+/b>%J(QD'QD%J0D%J(Qb"(QD%J/_|%J(QD I(QD%+/b>%H"$H <0… :|1b|%J(QDE'QD%J(_>%J(QD$J(QD 拘OD%J(Q|%J(QDI(QD%1D%J(Q$J(QD%(QD%J4/b>%J(QD'QD%J0D%J(Q|I(QD%J`>%J(QD$J(QD 'p 8`A&TaC!FT`>%J(QD$J(QD 拘OD%J(Q|%J(QDI(QD%1D%J(Q$J(QD%(QD%B̗/_>"(QD%J/D%J(Q| (߿o O_ 7p ,h „ "̗O`>ǐ!C 2dȐ!C cȐ!C 2dȐ!C)̗O`|/߿|'0_>˗_|#/߿|'0_> 2d`>ǐ!C 2dȐ!C +!C 2dȐ!C S0@O? O '߿(0_|'0_>$XA .T/_| cȐ!C 2dȐ!Cǐ!C 2dȐ!C )̗O`|/_ ̗O`|_>̗o |'p "Lp|1,!C 2dȐ!C W0C 2dȐ!C 2̧0_> ̗_|/_|/_>#/|ǐ!C O  <0… :|1|I(QD%2̧`>'? @?80_'p "Lp!ÄװaÆ 6lذaÆ5lذaÆ 6lذ| 6lذaÆ 6%J(QD"(QD%J/_|%J(QD I(QD%1D%J(Q (QD%JdOD%J1_|拘OD%J(Q|%J(QDI(QD'0|I(QD%JOD%J(Qb>%J(Qb|1D%J(Q$J(QD%(QD%J̗`$J(QD%'QD%J(1D%J(!|߿8`A8`A&TaC!FT`>%J(QD$J(QD˗`$J(QD%W0D%J(Q"|%J(QDE'QD%J(_$J(QD(QD%J4/b>%J(QDI(QD%J'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%'QD%J(1D%J(Q|I(QD%J!|'p  ;x|;80߿| ;x <0… :|!|,H? 4xaB 6tbD C`|G0|˗O`/_+/_>#_| ̗/_˗O`|˗/߿| ̗_|(q`>%J(QD%J(QD+!|/߿80߿|O`/| 70_>(0߿|/|˗O`_| /| H 'p "Lp!ÆB(q"Ŋ/b̘? (0o| ̗/_>|߿/߿(0߿|70߿| /_|70|˗? 4x| H*\ȰÇ#JHŋ3W0|O`>o`>_|70_>+_>'0߿|/|˗O`> 0F5jԨQF5R0_| w0@ /߿@7߿(0߿| ̗/_'p߿|? 4x| &L0a„ &L0a„8`A H*\ȰÇ#*'QD%J(1D%J(Q|I(QD%JOD%J(Qb>%J(QD"(QD%J/D%J(Q|%J(QD 拘O|Id/A O7P 'P߿'p "L_.\p… .\pB.\p… .\Pa| [h0'0_|˗/|˗o`|˗`|˗`˗o`>W0|o`|[p„ [p… .\p… [p… .\p…̷` /_>'0|_ 70_>+0@߿|߿| o| 7P`8`A&<`> *TPB *TP| *TPB *TP!|)|Ç P`/|O` W0|O`O`|/_|O`{|{(0Ç>|a>|Ç P` | _7p|7߿(`>?  _'P`>8`A&DO|)*TP!|)`>)TPB *TPa> *TPB *TPa>)TPB *TPB W0 Sx0B *TPB SPB *TPB Sx0B *TPB *TP| o o  <0… :|Ç>||{Ç>|aP`>||>|Ç'p 8`A&TaC!FTOb|I(QD I(QD%1D%J(Q$1D%J0D%J(Q|I(QD%JOb|I(QD )O O࿁7P? H*\Ȱ|#|+ϡCO/߿'p |߿? 4xaB Sx0ƒ*TPB *T0|'0_>˗O`|/_| *TPB '0| S(0_|˗/|/߿| ̗/|̗/|70_ '0| /߿| ̗O`*TP|)'0߿|o`| W`>/߿߿(0o|'p "Lx0_| 'p 8`A&TaC)̗O`|/_ ̗O`|˗Ç>d/_|c/_| /|O߿/߿(0|_>/_>/|70,h „)T80ƒ*TPB *T0|'0_/߿| ̗|'p "Lp!Æ p`/|O` W0|O`O`|/_|O` sС|s80C:t!| (߿o O ,h „ 2l`>/,(0 | _7p|7߿(`>?  _7P| H"̧`|̧`> *TPB *̧PB *TPB *̧`> *TPB !̧PB SH0_>Sx0B *TPB SPB *TPB Sx0B *TPB̧PB S0| SPB *TP| *TPB *TP| SPB *TPB *`>̧`> *TPB *̧PB *TPB *̧`> *TPB *TPO|7p|8P`>$XA .d|>|Ç'p 8`A&TaC!FT`> ߿8`A8`A&TaC=|Ç>||>|Ç6a=|Ç{Ç>|0C>|Ç>l!|{Ç>Ç>|`|P`a|(?@ 0@_O@ DPa> Sx0B *TPB SPB *TPB '0| S(0_|˗/|/߿| ̗/|̗/|70_ '0| /߿| ̗O`*TP| ̧`> *TPB *̧PB *TPB ̗/| S(0|_| /_>/|O` __@/|˗O`>$XA +OA$X ,h „ 2la>|Ç #| ˗_O` o`_//߿|'0'0o|O@ D`̧`> *TPB *̧PB *TPB 70| S/|_| /_> #o`| W0| ̗/|+o`| '0|)TPB Sx0ƒ*TPB *T0B *TPB *T(0_|Sx0 | _7p|7߿(`>?  _o`8`A&DOa|#O| *TPB *TOB *TPB *TO| *TPB COB ̧`|̧`> *TPB *̧PB *TPB *̧`> *TPB 3OB ̧`|Sx0B *TPB SPB *TPB Sx0B *TPB *TP| G0ƒ*TPB *T0B *TPB *T0ƒ*TPB *TPB (8P`7pO@ DPB >Ç>|!|,H? 4xaB 6tbD K/_|E'QD%2'QD%J(QD%J(Q"|E1D%J0D%J(QD%J(QDI,/b>%J(a>%J(QD%J(QDX0_|%J(Q"|%J(QD%J(QD%"'`$J(QD$J(QD%J(QD%JDOb|I(QD I(QD%J(QD%J0Ă H A$XA .dC$XA .dC%NXE'P`>$XA .dC(QD%J(QD%J(a$J(QD(QD%J(QD%J(a$J(QD(QD%J40 O@ DPB >Qa>%J(QD$J(QD 拘OD%J(Q|%J(QDI(QD%1ā 0_> o@O'P`|/| /|'P/,/A(? 4xa„%̧a>̧PB*TPB *TPB Sx0B'0_|˗/|˗o`|˗`|˗`o`>W0|3o`> '0߿|/| ̗/| SX0_| ̗`| ̗/_> ߿@/_O`|˗/| ̗/_>_| ̗/|˗O`8p| H*\ȰÇ ˗`_|˗O`>'0߿|o`| W`>/߿(080_>O`>/| O_+ A_'P`| '0| /_>o`| 7_>O`|/| /_>˗O` '0| 8pO@ DPB >0_|1̗/_o`>'P࿁ ߿߿| o`| /|/|O`|70|O/߿|O|/(0 o`> '0|O`>'P࿁/߿߿߿| @ /߿_/߿| HA8`A&TaC!"W0_| /_>'0|`>'0|/| 70_/| '0_| '0߿|'0|̷0_| ̗O`> _O` W0|`>o`|/| /_>˗O` '0|1bĈ#FD`'P70߿O@ /߿7P 'P8P`>˗/|O`> /߿_>$(0_̗/| `>_70߿o|7P࿁_7߿ |o8`A'p "Lp!ÆBD`"F1bĈ Ca#F\/bĈ1bĈ#Ft/b#F1bD k/bĈ1bD"F1bĈ拘/bĈ#F1|#F1bĈ1bĈ#Ft/b#F1bĈ 1bĈ#Fq`#F1bD"1bĈ#F0_|#F1bĈ1bĈ#Ft0 O@ DPB >Qa"'p "Lp!C ḨPB *TPB *̧`> *TPB *TP*O| Sx0B̧PB )TPB *TPB ) ̗o`|'`>8`A&'0| Sx0_| Sx0ƒ̧`> *LOa|/|'0_> ̗_|C/߿|'0_>'0_|˗O`| *T`|̧`> /_>'0|_ 70_>+0@߿|߿| o| /|'0| ̗O`'P(0|o˗o|8P`(0o7pO@ D`> ߿' (0_ ̗/߿|˗/|/_>  <0|)70_ 8P`(0@8p|8P`(0o  <0!| /|˗_|/|'0_ _' O࿁ <0̷`/|O` W0|O`O`|/_|`|/__|`> [` [h0B̷`-\pa| /|˗_|'0_/|˗o`|`> 7P8`A&T`>)0@ |o`߿?(߿|@ 0@O@/_|O`>'p| /`+`,XP` W` ,(0_ ,X`A O O࿁7P̗O`| ̗_|(߿8`A&,0@? ? 4xaB 6tb|1W0|E1_|E1|#F1bĈE1bĈ#Fh0| E4/b"惘/b1bĈ#Ft/b#F1bĈ E4/b"惘/b1bĈ#Ft/b#F1bĈ E4/b"惘/b1bĈ#Ft/b#F1bĈ E4/b"惘/b1bĈ#Ft/b#F1bĈ 1_|E1_|#>1bĈ#F|,H? 4xaB 6tbD 0 <0… 'p "LH0B *TPB *T0ƒ*TPB *TPB +O| Sx0ƒ̧`> *LOB *TPB *TO| W0B #0@ _ O@ /70_ 70 ̗O |/߿8`| ,80_+X| `,XP` ,X`'p "Lp!ÆB4/_|E0_|˗/|/߿| ̗/|̗/|70_ '0| /߿| '0_o`|` '0|˗`"拘b"F|/bĈ#F`|1|˗O` '0߿|o`| ̗O`> 'P/߿//߿|'0| '0߿|_> _ _>$/_` W`A ,(0_+X| ,X` O@ DPB >x0_|E0_|_0@70߿_'P`'0߿| _| _> /|`>/߿|? /|o7_(0o 7p8p'p "LH0B *TPB *TH0_>̧_'0߿|_|G0|`>/_>W0|;/_˗_/_3_S/_| +O| Sx0B̧PB )TPB *TPB G0ƒOo`70߿߿@ _ o@O'p| ̗/_'0|8_/``,XP` W` ,(0_ ,X`A8`A&TaC!̗/_>"1bĈ#F,a> C0@? Ϡ ,ϠA ,ϠA 4h_>$XA .dCE1bĈ#Fh0| E4/b"惘/b1bĈ#Ft/b#F1bĈ E4/b"惘/b1bĈ#Ft/b#F1bĈ E4/b"惘/b1bĈ#Ft/b#F1bĈ E4/b"惘/b1b#Ft0 O@ DPB >Qa>8`A&T!C$XA O@ DPB >QD-^Ę`"拘/b 拘O|5jԨQF5jH1_|E1_|Ȩb>5jH`> $ <0… :|1|%̗/_>"拘/b>"(a>%J(QD"(QD%J/|#/b"惘/b>(QD%J4/b>%J(QDA̗/|E1|I0D%J(Qb ˗/|%J(QD勘/|E1|I0D%J(b| 3Oa>%J(QD970|E1|I0D%J(Qb ˗a>%J(QD?˗/| $/A G A$H`> ? 4xaB*TPB *TPB K`> *TPB *TP Sx0ƒ̧`>)) *TPB *T` ˗a> *TPB *TP*O| Sx0B̧PB )TPB *TPB ) Sx| H| g | gРA 4/,h „ 2l!D"1bĈ#F0_D H*\Ȑ!,h „)TPB *TPB ) *TPB *TPB*TPB *TPB̧PB *TPB *T80_| *TPB *TPB*TPB *TPB̧PB *TPB *T80_| *TPB *TPB*TPB *TPB H A$XA .dC+OD%J(a>%J(QD"(QD%J/ć˗/|僘a|I(_>%J(Q"|#`|'QD%J(_> 0_>'0|(Q"|%J(Qć G0| I(QD%JO|=̗/|=̗/DS0@o'?˗o`|#/߿|̗o`|/|˗o`|(? H3/_'p "Lp!ÆB0ć 1_'1DS/|'0_ ̗O`|/|˗/߿| ̗/_>ˇ0_ ̗O`|˗O`|˗/| 'Q`|%w0D%J(Q$>0|5O@$(0| ,X` W |o?'? 7p ˗/_/_|G|'0_|/_|˗_|'P8`A W0|O@ DPB >Qa$&`>8 |+X| ̗/_ ,X`+X0_> ̗_|'0_> ̗_|0O?7?/߿O? G0߿(0_8`>/˗o@8`A&TaC!FT`>%J(QD'0_>˗/߿|˗O`|/_>̗|8?'p| ̗_|'p? O  48`A&TaC!FT`>%J(QD'P'@(? OO|'p|/_|/? o'p ;xp`>$XA .dC(QD%JOD%J(`$J(QD%'QD%J(1D%J(Q|I(QD%JOD%J(Qb>%J(QD"(QD%J/D%J(Q|%J(QD8`A H*\ȰÇ#*W0D%J(Q"|%J(QDE'QD%J(_$J(QD(QD%J4/b>%J(QD'QD%J0D%J(b|g0_|(QD%J/D%J(Q|%J(Qć G0| I(QD%JOD%J(Qb>%J(Qb|g0_|I(QD%JOD%J(Qb>%J(Q|K`>%J(QDI(QDI$@8`A&TaC!70| w0_Ĉ#F1bD 1bĈ#F80_Ĉ#F1|#`|1bĈ#F0_|#F1bĈ1bĈ#Ft/b#F1bĈ 1bĈ#Fq`#F1bD"1bĈ#F0_Ĉ#F1bĄ"F1bĈ拘/bĈ#F1|#F1bĈ1bĈ#Ft/b#F1bĈ E1bĈ#FL/bĈ#F!|,H? 4xaB 6tbD$J(QD%(QD%J(QD%J(a$J(QD(QD%J(QD%J(a$J(QD(QD%J40 O@ DPB >Qa$J(QD(QD%J4/b>%J(QD'QD%J0D%J(Q|I(QD%JOD%J(Qb>%J(Q|E'QD%J(_>%J(QD$J(QDW0_|%J(QD(QD%JOD%J(1_|I(QD%JOD%J(Qb>%J(Q|E'QD%J(_$J(QD(QD%JW0_|%JH"$H@8`A&TaC!FOD%J(1_|I(QD%J`>%J(QD$J(QD 拘OD%J(Q|%J(QDI(QD%1D%J(Q$J(QD%(QD%J4/b>%J(QDI(QD%J'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%W0D%J(Q"|%J(QD8`A H*\ȰÇ#*W0D%J(Q"|%J(QDE'QD%J(_$J(QD(QD%J4/b>%J(QDI(QD%J'QD%J/_|E'QD%J(_>%J(QD'P'@(? O'0_> O@̗o`|/ ̗/|'P8`A G0A'p "Lp!ÆB0D%J(Q| /|/_> ̗O`|/| ̗_|/|/_> ̗o`|˗/_/_|$G0_|%J(QD(QD%JO!|o?'? 7p ˗|'`>8_|/_ ̗/_/_|(? H| 3h`>$XA .dC+OD%J(a> ̗O`|/_> ̗O`|/? ̗O`|8PO?O 7p 7p|8P`>$XA .dC+OD%J(a> ̗O`|/_/߿|˗O`|'0_ ̗O`|C/_˗/@`'P`|8p? ߿| H| H*\ȰÇ#*W0D%J(Q"| (߿o 'p@ |@`|/|0@ o@$X | <0… :|1|I(QD%2'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%'QD%J(1D%J(Q|I(QD%JOD%J(Qb>%J(QD H A$XA .dC(QD%JOD%J(`$J(QD%W0D%J(Q"|%J(QDE'QD%J(_$J(QD(QD%B̗/_>"(QD%J/_|%J(QD I(QD'0|I(QD%JOD%J(Qb>%J(Qb|1D%J(Q$J(QD%(QD%J̗`$J(QD%'QD%J(1D%J(!|߿8`A8`A&TaC!FTOD%J(Qb>%J(Q"|#/b>%J(QD'QD%J0D%J(Q|I(QD%J`>%J(QD$J(QD 拘OD%J(Q|I(QD%2'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%'QD%J(1D%J(QA$X ,h „ 2l!Ĉ I(QD%J'QD%J(QD%J(Q"|%J(QDI(QD%J(QD%J0_|%J(QD 8`A&TaC!F8bE1fL@8`A&TaC!FOD%J(QD%J(QD (QD%JdOD%J(QD%J(QD (QD%JdOD%J( |,H? 4xaB 6tbD$J(QD%(QD%J4/b>%J(QDI(QD%J'QD%Jh0_|+O"|'P@ `>@ ̗_| 7_|0@߿| H| O@$XA ˧0BG0B SPB *TPB +O| ˗/|/_|/_/_/_>/_/|`70| ̗o`|'0_|)Oa|70_>'0_|'p`7?/_|˗o`'0_|'0_|˗o`'0_|/_8p'p "Lp!ÆB4/_"cO` /_>/| ̗o` '0_A /߿|߿'p`7p`| /|70_>0@߿|? W0_A ߿|O|O`>_|o|o| /|_|'0߿|/_>'0|  $? 4xaB 6t"|E0_|_0@70߿_'P`'0߿| O`| _> /|`>/߿|? o|o|7_(0|˗O`>0(0| O`>˗/߿|'P|߿߿| /߿8`A'p "Lp!ÆBD`_|˗O`>'0_| ̗O`> #_>o`| ̗_O`|O`O`>#oa#/|'0߿| '0|`> /_| ̗o` /_>_| ̗/|O`""1bĈ#F0_|-Oo`70߿߿@ _ 7P O'p| ̗/_'0|8_߿| HP` +/_ |߿|o /_> ̗/@o`߿| _70߿ _>$X| H*\ȰÇ+/b#F1bĂc/bĈ1bD"F1bĈ拘/bĈ#F`>1bą"Fa#F1bD"1bĈ#F0_Ĉ#F1bĄ"F1bĈ拘/bĈ#F1|E1bĈ#F/bĈ#Fa"F1bĈ#*W0_Ĉ#F1bā"F1bĈ拘/bĈ#F1|E1bĈ#F/bĈ#F!|,H? 4xaB 6tbD$O@ DPB 8`A&$OB *TPB *TO| *TPB *TPB)T80ƒ̧`>)@ ̗_| 7_|0@o`>$X0_ W`A ,/_+X| ` ,X | 'P'@(? O ̗_|/| ̗O |'p "Lx0_|Sx0B'0_|˗/|˗o`|˗`|˗`˗o`g0|3o`> '0߿|/|˗O`> ̧`̧`>)˗O`|/߿|ˇ0_ ̗O`|˗O`|˗/|*TP!|#O| _|˗O`>'0߿|o`| W`>/߿߿| o| /|'0| ̗O`'P(0|o|̗/@8p|8_(0o  <0!| (߿ '? O࿁8P`|/_ ̗/_>/_|(? 4xaBSx0B/| '0? 70߿/߿? ̗_>o|o| ̗o`_ _߿| o`|8p|8p|8p 8p8p|8P`(0,h „)̗O`|/_ ̗O`|/|'p '? O ,h „ W0B_|˗O`>'0_| ̗O`> #_>o`| ̗_O`|O`O`>3oa+o| [h0B̷p…)̗O`|/_˗/|˗_|K/_˗/?'@ O@ DPa̧|70߿߿ 80߿ _> OO࿁8|?#o`| ̗_>0(߿| HP` W0_+X| `,XP` ,X`,0@o'? #/|/߿|'P'p "LX`>/,(0,h „ 2l!Ăc/b"惘/b"a#F1bD"1bĈ#F4`"1|E1_ĈE1bĈ#:1_Ĉ#F1bD"1|E1_ĈE1bĈ#:1_Ĉ#F1bD"1|E1_ĈE1bĈ#:1_Ĉ#F1bD /b>"拘/b1bĈ#Ft0 O@ DPB >Qa"'p "Lp!C ḨPB *TPB *̧`> *TPB *TP Sx0ƒ̧`>)@ ̗_| 7_|0@o`>$X0_ W`A ,/_+X| ` ,X | H*\ȰÇ ˗/|1̗/_>'0_|/_|'0_|'0_| ̗_|70_>/| ̗o`>/|3_| 0|#/b>"拘/b1bĈ#F,/|E0|_| /_>/|O` _/߿O|o|_>o`|'`>߿+X`|W`A ,/_+X| ` ,X | H*\ȰÇ˗`˗/߿|70|(|߿|_> 70__ ̗O`'0_O`'P_'p`o 8p7p8p 8p@8p|8P`>$XA SPB *TPB G0ƒ70߿|/|˗O`/|G0߿|/| /߿|70|70|/|70| +Oa|) *TPB *T_Sx0 | _7p|7߿(`>? O _>`70_O ||O@W`,XP` W`A ,(0_+X` ,H0,h „ 2l!DG0_|#F1bĈ!0_|(߿'p 4H0A4X0A4hРA  <0… :|a"F1bĈ 3aE1_|E1|#F1bĈE1bĈ#FQaE1_|E1|#F1bĈE1bĈ#FQaE1_|E1|#F1bĈE1bĈ#FQaE1_|E1|#F1bĈ8`A H*\ȰÇ#*W0_D$XA .d? 4xaB8`A&TaC!F8bE1f<`"惘/b"x1F5jԨQF5RW0_|A1_|iOF5RO@ 'p "Lp!ÆB0|#/b>"拘/b>(QD%J4/b>%J(QD9̗O`>"惘/b"(a>%J(QD"(QD%J/|1|E1D I(QD%+`|'QD%J(_1|E1D I(QD!˗`>(QD%J/|1|E1D I(QD%+`|(QD%J/_| ߿'p 4H0A4X0A4hРA  <0… :|a;/bĈ#F1|E1|E1_ĈE1bĈ#"W0_|1bĈ#FQa"拘b"拘/bć"F1bĈ+`|1bĈ#F0_D"惘/b"a#F1bD"1bĈ#F0_D"惘/b"a#F1bD"1bĈ#F0_D"惘/b"a#F1bD"1bĈ#F0_D H*\Ȑ!,h „)TPB *TPB )%J(QD$J(QD 拘OD%J(Q|{/_|˗b'Q$J(QD˗`>w0D%J(Q$6̗/|k/|{ODI(QD'0|)'QD%J(_>I0_|0_|%JO!|O ߿@/_ ̗`|#80_˗O`|/_ O'p #`| <0… :|1|ILb|k/߿|I(_> ̗O`|/|'0_ ̗`|˗/|#/_|/|'0_|˗/߿| ̗`|W0_|I(QD%J`> =1| 8? 70_ ,X`,0@O? O ˗_|˗/|$/_ ̗/߿|˗/|/_> @$X`>708`A&TaC!FT`> 9O@$H0_| ,/_W` ,X` ̗O`|/_ ̗O`|/|'pO ?O@ ̗oO8P`>$XA .dC(QD%JOa|/߿|˗_|/_|/|'P࿁O ̗/|˗|o'P`| HA? 4xaB 6tbD$J(QD%S0@o'?`>O̗O`| ̗_|(߿  8`A&TaC!FTOD%J(Qb>%J(QD"(QD%J/D%J(Q|%J(QDE'QD%J(_>%J(QD$J(QD 'p 8`A&TaC!FT`>%J(QD$J(QD 拘OD%J(Q|I(QD%2'QD%Jh0_|%J(QD+OD%J(a>%J(Q"|#`|'QD%J(_>%J(QD$J(QD`>(QD%J/D%J(Q|%J(QĈ#`|(QD%J/D%J(Q|%J(QD̗0|%J(QD(QD%H"'p "Lp!ÆB,o`> `#F1bĈ 1bĈ#Fq`#F1bDG0|!1bĈ#FQa"F1bĈ#1bĈ#F0_|#F1bĈ+/bĈ#F1|#F1bĈE1bĈ#FQa#F1bĈ E1bĈ#:1_Ĉ#F1bD"F1bĈ#&1bĈ#F0_|#F1bĈ1bĈ#F0_Ĉ#F1C$X ,h „ 2l!Ĉ I(QD%J'QD%J(QD%J(Q"|I(QD%2'QD%J(QD%J(Q"|I(QD%2'QD%Jh`> $ <0… :|1|I(QD%2'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%'QD%J(1D%J(Qb"(QD%J/D%J(Q|%J(QD+/b>%J(QDI(QD%J'QD%J`$J(QD%'QD%J(1D%J(Qb"(QD%J/_|%J(QD I(QD%+/b>%J(DI@(0,h „ 2l!ĈI(QD%+/b>%J(QD'QD%J0D%J(Q|I(QD%JOD%J(Qb>%J(QD"(QD%J/D%J(Q|%J(QDE'QD%J(_>%J(QD$J(QD 拘OD%J(Q|%J(QDI(QD%1D%J(Q (QD%JdOD%J( |,H? 4xaB 6tbD (QD%JdOD%J(`$J(QD%W0D%J(Q"|%J(QDE'QD%J(_>%J(QD'P'@(? O'0_> O@̗o`|/ ̗/|'P8`G0A'p "Lp!ÆB0D%J(Q| /|/_> ̗O`|/| _|/|/_> ̗o`|˗/_/_|$˗O`>"(QD%J/D%J(Q| (߿ '? O࿁8_|'0_> /|˗o`|˗/_0@ O@ G0'p "Lp!ÆB0D%J(Q| /|˗_|/|'0_ (?/|'p?'@ ̗o/@8p| H*\ȰÇ#*W0D%J(Q"| /|˗_|'0_/|˗O`|/|ˇ0_|/_> (| O|8p@o  <0… :|1|I(QD%2̧`>'? @ O  O ? O'0_ ̗/_  O@'PO@O@ DPB >Qa$J(QD(QD%J4/b>%J(QDI(QD%J'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%'QD%J(1D%J(Q|I(QD%JOD%J(Qb>%J(QD H A$XA .dC(QD%JOD%J(`$J(QD%W0D%J(Q"|%J(QDE'QD%J(_$J(QD(QD%B̗/_>"(QD%J/_|%J(QD I(QD'0|I(QD%JOD%J(Qb>%J(Qb|1D%J(Q$J(QD%(QD%J̗`$J(QD%'QD%J(1D%J(!|߿8`A8`A&TaC!FTOD%J(Qb>%J(Q"|#/b>%J(QD'QD%J0D%J(Q|I(QD%J`>%J(QD$J(QD 拘OD%J(Q|I(QD%2'QD%Jh0_|%J(QD(QD%JOD%J(`$J(QD%'QD%J(1D%J(QA$X ,h „ 2l!Ĉ I(QD%J'QD%J(QD%J(Q"|%J(QDI(QD%J(QD%J0_|%J(QD 8`A&TaC!F8bE1fL@ ̗/@7P`| /_|˗o| /_˗o|(0_| ̗/_7p`|̗/@7P`| H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]Tf@;;PK{PKFJOEBPS/img/lobfise.gif!qGIF87ap?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,p H*\ȰÇ#JHŋ3jȱǏ C`> 4x@$XA .dC%NXE5nؑb|y,/_|=zѣG=zѣG0_>=zѣG=zc|ѣG=zѣG=r̗a<̗ϣG=zѣG=zܘ/|y$/G=zѣG=z1|/_|'0_|8߿'? 4xaB 6tbD)VxcF9vT/_|/_̗_/|˗O`yѣG=zѣG+o`3O`'0߿|o`|=zѣG=zѣE O|70/_| /? |,h ƒ H*\ȰÇ#JHŋ3jh1| '0߿|3O`|'0߿|o`|ȑ#G9rȑ#G +`|˗/_'p|߿'? 4x| H*\ȰÇ#JHŋ3jD0 $W0_ ,X`A ,X` O@ DPB >QD-^ĘQ|1g0_  /<(0,h „ 2l!Ĉ'Rh"ƌ滘am/F6nܸqƍ7nܸq|1w0_|˗o|7nܸqƍ7nܸ`> O@ 7p/_>$XA˗0a„ O@ DPB >QD-^ĘQ|#a>'P ,h@ O@ Dp`>$XA .dC%NXE5̇0_|!0_C$XA H <0… :|1ĉ+Z1Ƃ;/߿|!G0|7noƍ7nܸqƍ7̗`| ̇0_|mܸQb7nܸqƍ7n08|?'p A H*\Ȱ!B$X0,h „ 2l!Ĉ'Rh"ƌ;/|a ӨQc|ӨQF5jԨQƉ`>C`4jX1|5jԨQF5j(1|10_>51F5jԨQF5F̷0| %O H |,h „ 'p | $/,h „ 2l!Ĉ'Rh"ƌ-w1|W0_| ˧Q|!1F5jԨQF5B̷0| ̗/a| ˧Q#|1F5jԨQF5B̷0| ̗oa|Ө`|ȨQF5jԨQF-w1|ca|5"̗`4jԨQF5jԨb HA HP`|+/_/| ,X`|W`,XP`>$XA .dC%NXEx1|70|sOcG0|5jԨQF5j1F0_>+/_0 o`/߿|/_|/_o? 4xaB 6tbD)VxcƁ4f̗/_ (?_|'0_|/|/߿|˗/_˗/|'P ,X0,h „ 2l!Ĉ'Rh"ƌi(0|+O`˗o`#/߿| ̗/|'0|.ӨQF5jԨQF4j/|#_o` '0_||/߿O ,hP`>$XA .dC%NXEӨQ`| O`| /_/|_> ̗/|'0|.ӨQF5jԨQF4ja|#O`>/_'`>oo O@  <0… :|1ĉ+Z1|5̗oa|Өa|iԨQF5jԨQ#|5̗/|˗o"|'p ̗!B'p "Lp!ÆB(q"Ŋ'p "L ` ,X`WP`| ̗/_ ,X`W`+XP |,h@O@ , H8 | O@'p A H*\pa 64a 6,/_c/_| 6d/_| 0_Æװa|5l80_|̗/_|S/_| 6lذa| 6lh0| 6lx`>'p 8`A&T ̇0_>!/ƒC!B"D`>"D| O@ DPB >a>$.g0Ć 擸0|˗0_>I(Qb|(_7P'p`|˗o`8p| H*\ȰÇ#>̷0ą 0|3/|W0|!̗OD;`>3o`>/|%̷0D%J(QD;`|˗/|OO@ O|8P`|'p | o|80_7P` 80_>$XA .dh0|'0_|70_Koa 6lذaÆ 6doaO`>g0|W0_|'0_ C` 3/_|/߿|װaÆ /|``#aÆ 6lذaÆ 6_+_>G0߿|/_| /|g0|_>g0|'0_|5lذaÆOo8 |'P`o| <0… :|13/|/|̗`+/a̗/|!W0_> ˗`>˗O`7qĄ Hp GP`#/| G_0 <0… :|1ĉ8_`>(`>'p|_>(?8P  ̗/_ _>08 A0 08`A&T0a+O`> o`|'0_|%G0C 2dȐ!C 2dȰ``+`+_#_3a>c(0|3O``2dȐ!Á;0|O|0@O|'p "Lp!ÆB(a>#o`| W0|W0߿|%70|_>O` 3/|/_|7qĉM8_'N8qĉ;/_|˗O`|g0|˗/_> @7p|0@O@ ̗ A A ˗? 4xaB װaÆ5lذaÆ 6lذaÆ 5l80| g0_Æ̗a|kx0_ 6l` 64aÆ 6lذaÆ 6TaÁ kذ`>6`| K/_Â5lذaÆ5lذ| 6lذaÆ 6lذ| g0_Æװ|ˇ0_| p`| 6lذ!| 6lh0_Æ 6lذaÆ 6l0_Æװa|5l80|̗/|5̗/_Æ 6l| H*o… .\p… .\pa| g0… ̷p| 8P ,0@ 0@ H*\P!|,h „ 'p "Lp!ÆB(q@$X 0 JÚ/c]8`A&T? 'p A H | O@8`A8`A'p "Lp 0'p (? O@ D? 4xaB 6tbā$J0_|%̗/|̗/|I/_3/_$J(0_|%̗/|̗/|I/_>%J(QD$J0|˗Oa|˧0_>˷0_COD!̗/|˗a| 'Q|I(QD%&'QD0_)̗/a|˗0_>'QD0_)̗/a|%̗OD%J(1a>'0@ o7p࿁7p`O|7p7p|80_7p@8p /_/ 0@߿߿|߿|߿(08p8_|/(0߿|'p ̗? 4xaB 6t"| ̗_>`o`O`|̗/b|k`| =̗`|3`#`| ̗o`|/a>E̗`̗`">̗/bĈ#Fa> _>/| '0_| ̗/_ O`O`|70|70߿|/_a| g0_|W0_>˗O`|/a G0|+/|+/_|˗/| ̗/@o _>$XA .dC g0| 70|!'0_| '0_|̗/_/|/|_|O`|/_>`#`/߿|/| /_#/_>/|˗/|O`'0߿|o`|E1bĈ'p o`'P'p|O |/O@ 0@ (`>'p A 8?'0߿|/ 8? 080_|o? _/߿߿(`>'p |'p@ 'p@__>/|˗O`> (? 4xaB 6t| _>`>`>`E`|̗/||70߿ ߿ H|g0_|W0|'P|_>|$Hp`|G A˗|O|__>  <0… :|` /߿| '0_| 70|o`˗ |'p| A_|O`o`>/A #_>_>'0_ /߿| / #/_> G0߿| /߿| /| /|˗O` <0… :|`> ˗/| ̗|߿|?O A70| GP`#`>o'P`80O` _|O_/?7P O`|8p` 7p|70|/߿|'0|(_߿| H*\ȰÇ1b|勘/|;/_D̗`>1bĂ 1_g0_1bĈ#F0_Ĉ3/|0_ET/|w0_Ĉ ;/|0_Ex0_#F1bD"F0|˗0_>%̗/"|0_"FX0|˗0_>%̗/bĂE1bĈ#F1bĆ0_| C/_>E,/_%̗/B8`A&T/|-/|!̗Oa|.\H0_| .\p… .\Pa .\0_|%̗/+/_˷a| ̗/|%̷p… K/_[/_|˷_|.\(0_| .\p… .\p!|,h „ 'p A$(? O@ H |,hP ,08?$XA O@8@$X`>'p H'p "Lp!ÆB(q"Ŋxŋ泘? 4xaB 6tbD)VxcF9vdH#rI4yeJ+YtfL3iִygN;yhPC5ziRK6ujTSVzkV[vlXcɖ5{mZkٶun\sֵ{o^{p` 6<5 ;;PK!!PKFJOEBPS/img/pco81006.gifwGIF87a?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`Ê`>8`A ̗/a|30@˗/,h „ 2l!Ĉ'Rh"ƃ ? 4x|̗/߿|'p`'p |˗o`| ̗ A $H|8`A&TaC!F8bʼn ̗/E70_>/|70_>)̗|,ZhѢE-Z0_>70_> ߿8p`o`>̗o /߿|/_˗O |@8p` oO@ DPB >QD%G0_ ̗O`|/_>O|'?(`>O /_Oo80?''? 4xaB 6tbD)V/|/_ ̗O |' O@O /_ Oo OO <0… :|1ĉ+N̗`|/|'`> OO ,/|/߿| ,/|'p?' O8`A&TaC!F8bʼn ̗/|/|'0_|/|/_̗/|˗O`|˗/a|'0_> ̗/߿|w0_> ̗_|/|,ZhѢE-Z`>o O? '? O࿁ O@?#8?80߿ OO <0… :|1ĉ+NO߿'? o@0@ 0 ߿ o࿁'? o'߿ H*\ȰÇ#JHExb-wa/^xŋ/̗ŋ/^xŋ/^x"|8`A&TaC!F8bE1fԸcGA9dI'QTeK/aƔ9fM7qԹgO?:hQG&UiSOF:jUWfպkW_;lYgѦUm[oƕ;n]w10@ O | ?'p? ? ߿7P?߿'߿ @ ̗O`|/?7P߿  O70/|'0_> ̗_>$XA .dÆ'0_|+/| '0_)̗`|/_>/_>!̗`|/|˗_|g0_|/_>̗O`|/|W0_> ̗a|/_|/߿|'0_>1̗O`|/|˗/߿|!B"D˗o`>̗`|#o`| +/_ ̗/_/_>!̗`|˗ ||'?/_|/@˗/߿|'0_ /|7p| ̗/߿| ̗O`|/_ //_ ̗O`|/_|'p "Lp!Æ>O (@/A(߿70߿@ 0@ o`o 7'P | '?@  '߿'p|˗_|/|˗/,h „ 2l!ā O 7_|7p|/_/_ 70_|'0_7P | ? 7߿'p`|˗|'p | O O@O  ̗|˗/@ O࿁(0_/|˗_|8`A&TaC!̗_|#/|/| /_|8߿'?G_|˗`|80߿ O@O O@ O? /|7p| O| O|˗_|7p@˗/|'`>'p "Lp!ÆB/|W0_>̗O`|S/_|/|'p`'p|˗O`|/@߿8`>/|/_>/|̗?@ ̗O`|/?O? O80,h „ 2l!D  7p@$070߿'_8߿'P`|/_|/߿|OO? H0_> ̗O`|87p O|'?/|8p|'0_70_ <0… :|1ĉ+Z1ƍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3Ν<{dϟ?/_?|c|~ 0@ H*\ȰÇ#JHa|U1_Ŋ+VT0@ H*\ȰÇ#JH!|'p "Lp` .\p… 'p`>$XA .dC%Nh`>8`A&T80… .\p…80,h „ 2l!Ĉ'R408`A&T(0… .\p…8p ,h „ 2l!Ĉ'R,08`A&T(0… .\p…[p… .\p… .\p!B <0.\p… .20@ 8`A&0| -̇0_D˗O`|70_>"F/_ĈEa>/_> W0_#F1"|/_| ̗/_>/_| '0_|˗`/_|80/_70_>'p "Lh0B ˗/|70_|˗/|/_| Oo '? o ,h „ 2l!|˗O`|'`> ?O`>G_>'0_˗_> O O@ D`>  ̗_| '0߿|˗/|/_/߿|/_ ̗_| ̗O`|'0_|/B *TPB ̗/|˗_|˗`/_ O`|O`> #0@O'p "Lh0B /|˗_|/߿|/|˗o` ̗_>'P߿| _8`A&TaC'p | O|8_o`(0|8_? /_ ̗o`>$XA SP|O`|˗o |__'p`> /70߿| H*\ȰÇ/_|/_>'0__|`>'0| G0_> ̗_|"DA/߿|O` ̗/|_|/߿|/_>+/|#O`|/D!Ba| ̗/_˗/|/| ̗/_>'0_>'0|7`>80߿8`A&4OB˗o`>'0_|˗/|/_| O// o`|  <0… :|1ĉ哘"E(2G"E%G"E)RH"E"G"|H|H"E)RH"EH"E)RH"E)RH"(RH"E)RH"E)RH_> 03a   <0… :|1ĉ+ZX0F&X0| /|70_0bĈ#F1b1F70|0@'?7߿| o`o`> ̗_|/߿| <0… :|1ĉ+ZH0F˗O`>OO_߿|' '߿8`A&TaC!F8bE È0|o`|+/_|˗_>˗/߿|_|#O`|_|aĈ#F1bĈb> ̗O`>˗o`'0_|#O`|'0_>'pO7߿'p "Lp!ÆB(q"Ŋ/̇a|O`/_| '0߿| '0߿|'0߿|#/|70_|aĈ#F1bĈb>˗o`>0@ /|o|˗_| '0_| '`>(0_'p "Lp!ÆB(q"Ŋ/̇#F僘#F1bĈ#FaĈ|È#F1bĈc|1bĈ#F1bĈ#FaĈ#F1bĈ#F1Ḟ#F1bĈ#F1b1F1bĈ#F1bĈc|1bĈ#F1bĈ#FaĈ#F1bĈ#F1Ḟ#F1bĈ#F1b1F1bĈ#F1bĈc|1bĈ#F1bĈ#FaĈ#F1bĈ#F1Ḟ#F1bFaFaQDO@ DPB >QD-^ĘQƋ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G/'P  G A(߿(?O@ DPB5lx`>? W`>70߿@ /,h „ 2l!Ĉ ̗/|̗O`|'0_̗O`|1bĈ1_>=G0_>/|G0_> ̗/_Ĉ#F1b|/_| ̗/_>/_|_|/|70_|"F1b/|˗O |'߿߿߿8`A&TaC!BO'_(oo`>$XA .dx0_Æ8߿| 7P?7PO?'?? 4xaB 6tb ?A 7p |? ? O8`A&T| ̗O`| 70_|O|'? 4xaB 6tbD (_ 'P`˗/|/ ̗O |'p "Lp!C60_'0|_|`|/| ̗`|o`|#F1_D ̗O`>˗O`|/߿|˗_|/|1bĈ#F0@ _o`@8߿  O@ DPB5lx`>߿|o@ O o'߿8`A&TaC!F8bE1̗1cƌ3f̘1cƌ3f/_ƌ3f̘1cƌ3f̘1|3f̘1cƌ3f̘1cƌe̘1cƌ3f̘1cƌ3˗1cƌ3f̘1cƌ3f/_ƌ3f̘1cƌ3f̘1|3f̘1cƌ3f̘1cƌe̘1cƌ3f̘1cƌ3˗1cƌ3f̘1cƌ3f/_ƌ3f̘1cƌ3f̘1|3f̘1cƌ3f̘1cƌe̘1cƌ3f̘1cƌ3˗1cƌ3f̘1cƌ3( <0… :|1ĉ+Z1ƍqȑ#G 'P $? 4xaB 6tbD M8qĉ'N0_>;`'N8qĉ M8qĉ'N0_˗/߿|̗/_> ̗_|'N8qĉM8qĉ'N`>(0_˗O`>'p "Lp!ÆB0D%J(QD 'p`@'0_|8`A&TaC!FOD%J(QD8P| O`|˗? 4xaB 6tbĈ$J(QD%J(0_'0|/| ̗OD%J(Q"|%J(QD%J0@ ߿O ,h „ 2l!Ĉ I(QD%J(Q"|$J(QD%&'QD%J(QD (QD%J0D%J(QD%J(QD%JX0D%J(QD%J(QD%JX0D%J(QD%J(QD%JX0D%J(QD%J(QD%JX0D%J(QD%J(QD%JX0D%J(QD%J(QD%JX0D%J(QD%J(QD%JX0D%J(QD (߿O ˗ |7P ,/ 3hРA+/_|gРA 3X0_4hР8`A&TaC!F81_>/|g0_|/߿|0_|7a/_|[O`M`&2̗ |'p ̇p`|C!B_|/|/|'0_>70_|˗/@'p`|˗o|o|˗/| O| O|O` o'p  ;xA3``(0_|(0@'0|O` 7P`|O`>/|O@ w70_|˗/@ O| ̗/7_| ̗/@@ ̗/_>0o ,h  ߿@ 70_>O@$80_70߿| /_>70_ '0_A`#/߿| /_> _>_| W`+X` /߿|/_ ̗/_>/߿|/|70_>'0|O` G0_'0|˗O`>,X` ̗/_>/_ @$8`>_߿| _/߿O| o| ̗/_|'P`O`>'P8`A_| o`O` '0,h  ̗_|/_'0_ ̗O`| /_|˗O`>'0߿|`| G0_>+`>_>/| ̗_>_| ̗0a| &40@/߿|_o/߿? 80|˗O`>0@߿/߿o'p "$0@8@O'? HP`|˗/_>'0|/_>+/_|O ? `>߿|O|/_| '0_|O@ w ̗/_>'0|_o`| W0Ao`>_|'0_O` '0,h „ 2l!Ĉ'R81E/_|˗/|˗O`|˗`|+/a>'p|/߿| _70߿8`A&TaC!F8bʼn,ZhѢE-ZhѢE-Z,ϢE-ZhѢE-ZhѢł,ZhѢE-ZhѢE-Z,ϢE-ZhѢE-ZhѢł,ZhѢE-ZhѢE-Z,ϢE-ZhѢE-ZhѢł,ZhѢE-ZhѢE-Z,ϢE-ZhѢE-ZhѢł,ZhѢE-ZhѢE-Z,ϢE-ZhѢE-ZhѢł,ZhѢE-ZhѢE-Z,ϢE-ZhѢE-", 'p "Lp!ÆB(q"Ŋ/b̨q|9rȑ#G9rȑc|9rȑ#G9rȑc|9rȑ#G9rȑc|;`>#0@_>$X0_+X_|+X` 0@߿'p`|'P O@3/_| 4h_|˗O` $ϠA ̗_| 4h`> 4H0_|gРA+o`| ̗Ϡ $`|4hРA/_ ̗o`|G0_> ̗O`| ̗/|4hР /߿|4H0A,O`> 4h_> 4H0_|˗O`| O @ ̗/| o`| 7_˗o`>/_˗O`>'p࿁ <(0_G0_>̗/_ ̗O`|Ch0_|˗O`| O o ˗O`|7_ 7_˗o`/_˗O`>'p࿁ , /߿|/_ ̗/_>/߿|/|70|#/| '0|'0_|/| /_>w(?'? /_|/|7p˗_|/߿|˗/| ̗/|O`> ̗/ 7_|'0| /_> ̗_| '0|O`| HA/|'p O|'?'߿| O@/߿|70|_|+(0|/_> +_> /|`O`>'0| ,Xp` ,Xp |߿|/߿ ߿߿|_> 7_>80߿|˗O`>'p _>|? 4x|/_|#0 O'P|/߿@߿|߿| _ _>'0߿|O@ 70߿| '0? /,h`,o`| /_>/| /|O`/_>o`>/_> /߿| '0߿| 70_ ̗/|/|70_>4o`| /_>/| ̗o`> '0|`o`>_|'0_O` '0;xA/_|˗/|˗O`|˗?70@ ߿8P`> /߿?˗O`| '0|? 4x |o? ? O@#_| ̗/_>˗/| ̗/_ |7P| O |o`O|/_| '0_|O@  <0… :|1ĉ+Z1ƍqȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qȑ#G9rȑ#G qGq@  |( HP` ,`A̗/_> O@ DPB sСC:tСÆ ̗O`|/_ ̗O`|˗O`|/C"'0| ̗_:tСÄ:,|#0@ H*\Ȱa|'0_> /_>'0_|'0_>9`|˗/߿|/_3/_>#` +/_|7`>7? 4xaB -\0…[80_|[p… ./|`|+`| '0|_|'p "La +/_'`>/_ o|/_ ߿ H*\/_> ̗ |O (? O ,/|O`| '0| '0`#/| /_> 4hРA ϠA G0_>/߿|/|#/|70_>'0|O` gРA 4hР|'0_>˗`> ̗/_> ̗O`| G`>/߿߿߿|?7P` '0_|O`  <0B.\`| '0߿|'0| '0_A O| /| /_>8`A&T0_ ̗`|/|'0_|'0_>-,`| '0_| '0|O`>/_| /| '0߿|[p…-\0A /߿__߿|O|'0|O`>'P ,h „ 'P7Po 'P࿁_'_'P`|(`>(_> '0?߿|o`>$XA "̷p|O`>'0߿| G0_>+/a>O`>/| .\p… .\0a .\p… .o… o`߿ ߿| /_ 7p|O_O@ DPB >0_|"F1bĈEq`#F1bĈ#F1bĈ#F4/bD1bĈ#F1bĈ#F1bĈE1bĈ#F1bĈ#F1bĈ1bĈ#F1bĈ#F1bĈ#*1bĈ#F1bĈ#F1bĈ#FT/bĈ#F1bĈ#F1bĈ#F0_Ĉ#F1bĈ#F1bĈ#FQa#F1bĈ#F1bĈ#F1|#F1bĈ#F1bĈ#F("R| H*\ȰÇ#JHŋ3jx1G9rȑ#G9r0G9rȑ#G9r0G9rȑ#G9r0G9rȑ#G9r0G9r`>7p࿁70߿ '߿7p ,h „ 2l!Ĉ I(QD%J/_> ̗`|/_> ̗O`| ̗O`|0@ H˗Oa| O| *T0B *TPB *TPB/|70߿|/|/|˧`COB̧p`>;OB SPB *TPB *T_|0@ O ˗O`| O O@/_|/_|˗o`>/_|˗O`|˗o`|/_/_/_>#/_|7`>'p  <0… :|1D ̗O`|80O@ O8`O`>O`>'0_`| G0|'0߿|_|g0߿|'0_|˗O`>'0A ? 4xaB 6tbD /|˗/|/_|/| #o`|̗O`>o`|70|#/|˗O` 3_| +_ '0|Mdoĉ'N8q|70_> ̗_|/|/|1|˗O`>'0| 7`>/߿?`>7P| _|O`|(0߿|(߿|/,h| H*\ȰÇ#JT0@8@߿߿7p o`_/_˗O`> '0|˗O`'0߿||O`/| '0_ ,/,h „ 2l!Ĉ'R`> o@߿70˗o`70_|/_|'0_/_|/߿|˗/|  <80,h „ 2l!Ĉ'Rhb>.^x|/^xŋ/^`/^x0ŋ/^xŋ/^xE.^xŋ/^xŋ/*wŋ/^xŋ/^xQa/^xŋ/^xŋ ]xŋ/^xŋ/^Tŋ/^xŋ/^x|/^xŋ/^xŋxŋ/^xŋ/^0ŋ/^xŋ/^xE.^xŋ/^xŋ/*wŋ/^xE]tE]@8`A&TaC!F8bE1fԸb>9rȑ#G9r1a>9rȑ#G9r1a>9r1#|'p "LH0B)$/_|`> ̧_|SP*TPB *TPB *T80_>)TP!|  '0B /߿|)T`> ̧PB)Tp`> SH0_>  /_ ? W0_|˗_|˗/߿|/_>#` +/_|7`>7?˗O`>'p࿁ O@ $!BC`>W0|"DP`> ̇!B"/|'0_|/߿|'0|/߿| #/|/_ '0_'0|G0_|O`>/|`|O`>/|C!"D_/_|80߿ /_>/˗/_>0'0|8 O@ D|߿_/߿/߿#/| ̗o`>`+(0_|W0|O`>'0_|'0|˗O` ,X`A ,X`'0|/߿|/߿|O`G0_O`| /_> /_O` '0_ ,X`+o`|70|˗O`>+XP`> _/߿_߿|߿| _ O`>'0|O@ 70߿| '0? ? 4x`>"`| '0߿|'0| '0_A O| /| /_> 70߿| '0߿|? 4xa70_|O`| '0| ̧P`> '0| '0|̗O`>G0߿|'0߿| '0|`>'0|˗O`*TH0B #0@/߿|/߿߿߿| o/_| '0? O|'0|O'p "L80_˗/|o`| '0| 'P࿁_'_'P`|(`>(_> '0?߿|o`> ̗/_>'0|˗_>$XA"D_> '0|_>#/|̇_>O`>/| ̗_>_| ̇!B"DX0_>"Dp`>"D!B"D!‚"D|߿|o`/˗o` 80|8_߿(0_|˗/| /_>8`A&T0_|.\`|-\p… .\p| .\0,h „ 2l!Ĉ'Rh"ƌiĘ/_|5jԨQF5jԨ1a>5jԨQF5jԨQ|5jԨQF5jԨQƅ4jԨQF5jԨQF iԨQF5jԨQFӨQF5jԨQF5.̧QF5jԨQF5j\OF5jԨQF5jԸ0F5jԨQF5jԨqa>5jԨQF5jԨQ|5jԨQF5jԨQƅ4jԨQF5jԨQF iԨQF5jԨQFӨQFiB(? 4xaB 6tbDH"E)R0_>Q0łG`> ߿| H| g`|3hРA gРA3hР /A '߿'p 4H0˗ϠA 4h_|/_G0_|˗O`|'p`>$80_ '0_70_W` ,/_ W` ,X0_ ,80_ '0_70_W` ,/_ W` ,X`|/߿|˗O`|/| ̗_|,80_| ̗/_/_|W_|˗`70| ̗/| '0_|˗/|O7? 4x`>"`|˗/@o ˗O`|70_/|70߿| ̗/'0|8 O@ D8`>/߿߿߿|O@̗O`>˗/߿|/߿|O`/|O`>O` W0_'0|˗O`>,X`,X`̗O`>/_'0_'0| '0_>'0| /|`|O`>/|+X` ̗`> '0|̗/_>`'0|O`>#o`> 'P@(0_>_| o`O` '0,h |"D/|O`O`>O` ߿|'P` ̗O`/|_>_|  <`| ̗/߿|/߿| '0|%$ |?_߿/߿(0o| ̗/_>|'P`O`>'P8`AC!'P/߿__//| _'0߿|O@ 70߿| '0? /,h ‚70_|˗/߿|˗O`>KH0|O`|O`>'0|'0_|'0|'0߿|+O`| '0|O` &̗0aB'0|˗O``| W0|g0_| '0߿|˗O`/| /_>K0a„ ˗0a‚ o`| ߿| /_ O O | /_|˗O`>˗/| H!D? 70߿|_> ̗/|'PO@'p|o`> ̗/_>'0|˗O`>$XA ̗/_ .Lo… .\p… [pB.\p… .\p… .T/_| .\p… .\(0… ̗/_>$XA .dC%NXE-ӨQF5jԨQF5.̧QF5jԨQF5j\OF5jԨQF5jԸ0F5jԨQF5jԨqa>5jԨQF5jԨQ|5jԨQF5jԨQƅ4jԨQF5jԨQF iԨQF5jԨQFӨQF5jԨQF5.̧QF5jԨQF5j\OF5jԨQF5jԸ0F5jԨQF5jԨqa>5jԨQF5jԨQ|5jԨQF'P ,h „(? 4xa̗/_> Sh0ƒ˗/_> ̧PB *TPB *TPB ̗OB a>*D`W0B̧_*TH0B 'P ,h „#0@_>$X_> 3X0_4hРA/߿|˗/_>/_|7`>'p /_>/_>70|/_'0_|/_| '0_| '0|/_| `> @$XР|˗_| '0_w`>O`>O` ̗_|#/|̗/|̗O`>O`>'0_|/|/_>w˗O`|˗O`| '0_|˗`|˗`70| ̗/| '0|80_||߿ H(߿| _/߿|70߿_>$80|`| /|`+(0_|W0߿|O`>'0_|'0|˗O`> ,X` ,Xp`>O`>O` ̗_| 70_>+o`> G0_>O`/|/߿| '0߿|/_ ,/_|O`#/_| '0_/_|/_| ̗/|(߿/߿/o|o`|'0|(? /|`> $ #o`|̗O`>o`|o`> 'P@(0_>_| o`O` '0,h| /_ '0_O`>CX0| '0߿| '0_| ̗/|O`>/_|'0| '0߿|+O`| '0߿|O`>ˇ!B/_|/_| ̗/|8߿߿| o|7p`˗/| `>(0| '0|(߿| H+o`|̗/_˗/| ̇ |8 /߿ o`> ̗/|'P'p`G?˗O`| /|? 4H070߿| /| ̗/|˗O` '0_| ̗/| 70| /_> /߿| '0߿|<80_" o '߿|70߿O@ ߿| (0@| @'0_|O`|  <0!|SPB̧PB *TPB)TP„O@ DPB >QD-^Ęqa> +OF5jԨQF1ӨQF5jԨQF5.̧QF5jԨQF5j\OF5jԨQF5jԸ0F5jԨQF5jԨqa>5jԨQF5jԨQ|5jԨQF5jԨQƅ4jԨQF5jԨQF iԨQF5jԨQFӨQF5jԨQF5.̧QF5jԨQF5j\OF5jԨQF5jԸ0F5jԨQF5jԨqa>5jH#4H#4H#(,h „ 2l!Ĉ'Rh"ƌ7^Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#G9rȑ#G9&Ǒ#GqGqGqQBO@ DPB >QD-^ĘQƋ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G1˗/ǂ /,h „ 2lX0Cs`>8`|O@ DPB >a|Kb ̗/a|(QDIl/D '0_˗OD%J(Q|'0|/_| /_|/|Oo࿁8`A&T| ̗O`| ̗/_>/_> ̗O`'p7| H*\ȰÇG0_>o`|o`> 'p߿|O /߿8`A&T| ̗O`|/߿|O` _/߿@$XA .dC #/|70|O` ̗O`O`|o`|"Fao`>/|̗O`| '0|/߿|1bĈ#F0_> 70߿| ̗_+/|O`>'p|70,h „ 2a 70|o`> '0_>O`> /߿  <0… :|a|O`| ̗_| ̗O` ̗O`> '0|O`|1bą":̗O`/_'0_|'0|O`| '0_>E1bĈ#:̗/_> O7Po _o`o`>$XA .d(0_Æo`>'`>߿o߿߿'p "Lp!ÆB1D%J(a> (QD%J(Qă$J(QDIh0D%J(QD%J(QD!(QD%J(QD%J(QD (QD%J(QD%J(QD (QD%J(QD%J(QD (QD%J(QD%J(QD (QD%J(QD%J(QD (QD%J(QD%J(QD (QD%J(QD%J(QD (QD%J$DI$DI$DI$D? 4xaB 6tbD)VxcF/ȑ#G9rȑ#Gȑ#G9rȑ#Gȑ#G9rȑ#Gȑ#G9rȑ#Gȑ#G9rȑ#Gȑ#G9rȑ#Gȑ#G'P7P@7PO@ DPB >a>'a| IOa$Jx0_> ̗`|/_> ̗O`| ̗O`|僘`> {O|1'QĄ$>̗o`> -'_> (Q|'0_> /_>'0_|'0_>A̗o`> A0_| !'QD$>̗/|7`>7?'0_|˗/|70_|70_|70|/_O@ D`|0@ O ˗O`| O O@'0߿| O| O| ̗//_˗o`|˗o|˗/߿| _|˗o |O@ D0_„ O`/߿|˗O`> '0_|/߿|˗O` '0_O`˗_| ̗/a„ ̗O`|308| O /| '0_/|O`>˗/|˗O` /_|/߿| /_>/| 4hР 4h|70_>_|70| /|+/| ̗o`>_| gРA 4H0_> ̗|#O`|˗O`|/A /|O` G0|̗o`| /_>+`>O|_| '0| HK0|/_|O` ߿߿| o`˗/߿|'P߿|߿ _>$XA /_̗o`|/|˗/|'0_> /߿|O`>'P_'p | /?O|/|/@0@/߿8`A&̗0aB˗o`>_|̗O`> /߿|/|O`>O` /_>K0a„(߿(߿O7PO@ ̗/| '0߿|#/|70_| /_>'0߿| ̗o` _| '0| ,X`,X` O@߿|O| 7P`| O|oG?O@ DPB 67`>_G?70@/_| ̗/_>//_> O`|˗O`>O@ D0_„ &L0!| H*\ȰÇ#JHŋ1˘1|3f̘1cƌ3f̈1_ƌ3f̘1cƌ3f̘1|3f̘1cƌ3f̘1cƌe̘1cƌ3f̘1cƌ3˗1cƌ3f̘1cƌ3f/_ƌ3f̘1cƌ3f̘1|3f̘1cƌ3f̘1cƌe̘1cƌ3f̘1cƌ3˗1cƌ3f̘1cƌ3f/_ƌ3f̘1cƌ3f̘1|3f̘1cƌ3f̘1cƌe̘1cƌ3f̘1cƌ3˗1cƌ3f̘1cƌeQF? 4xaB 6tbD)VxcF/ȑ#G9O80߿'? H*\ȰÇ#6'a|'`|̧0D+ODW0_> ̗O`|/|;O"|/| I(Qa> ̗`>1D (Q̗`|#O`|co`|I$b Ka>%'a˗o`/_>/_>'0߿|/_| /_|/߿| ̗/_>˗OD(߿'? `>8| ̗/| '0_|˗O`|˗O`|/_/_>/_#_|˗O |O@ DP`> ̗O`>_>'0|`|_|˗_|_>'0߿| ̗_|'0B *T0_̗O`|/B '0|'0߿|#/|'0_|/_>'0| ̗O`|'0߿|/߿|)TP| *$_|_>'0| W0|'0߿|/|o`|'0߿|  <0…+/|G0|_̗O`/| '0|'0| /| ̗/| /_>O`> .ǐ| ̗/_>|_/_o`'0_|_| 70?O@ DPB̗`|/|_˗/| `>/߿?8P˗_>˗_ `>/߿8`A&OB'0|'0߿|#/|'0__|̗/߿| 70_/߿| ̧PB "̗ |'߿'p o`>_|̗O`>/_>˗O` '0_|_/| '0_ ,X`A ,X`'p|o`> ̗/|˗/| '0_|'`> _'p "Lp!Æ0߿(0_| /_>'0߿|/_ O`//_|O`>$XA O@ DPB >QD-^ĘQƋ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8rȑ#G9rȑ#DŽ8`A&TaC!F8bE1fԸcGA9dI'QTeK/aƔ9fM7qԹgO?:hQG&UiSOF;;PKX"wwPKFJOEBPS/img/pco81048.gif:zŅGIF87aXn?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,Xn H*\ȰÇ#JHŋ3jȱǏ CI@$XA .dC%NXE5nT <0… :|1ĉWbŊX|+VbŊ+ ̗/_Ŋ+VXbŊWbŊ X|+VbŊ+/_+VXbŊbŊ+Wbň*V1_Ŋ+V̗O`|+VXbŊ+70_Ŋ+V,bŊUX1b+V`|+VXbŊ+G0_Ŋ+V,bŊUXb+V`|+VXbŊ+W0_+V80_Ŋ!X"|+V81|*VXQEUTQEP>? 4xaB 6t80Ç>ÇÇ6w0_>|Ç>|_>>|Ç=|Á>||>|!|{Ç>|ÇKÇ>|(0Ç>Ç Ç2̗0_>|Ç>|_>>|Ç=|C>||>|| {Ç>|Ç[Ç>|/Ç>ÇÇ.̷0_>|z衇z'p A ,X`'P ,O` ,X`| ,(`>8` 4h`>4hРA 4hP`>/_> ̗/|˗o`|˗/|̗/_4h`|  <0… :|1ĉk|sb*˗|3/_Ŋ C/_/߿|/| '0_> ̗`> ̗O`|h0_UXbŊ+V/|%70߿| ̗/_O | ,h`G0_>˗/|/_g0_>'0_|˗/| ̗/_>'0_| /_>G0| #O`|,'p "Lp!ÆB(q"`>_/߿_'p  ;x || ߿| <`|O`>o`>'0|˗O`|w_|/߿|/_> /_``>O`>O`  ,AO@߿8`A̗`| '0| '0|O`  gP`|/߿|#/߿|/_|#|/| 4h0AO@ DPB >QDIWa|O`O`>_|U4b|/_>o`̗o`O`>__|Q̗`> o'_߿| O/߿ O ,hP`  <0… :|1ĉ囘b|/_|O`| '0|˗|8? _O ,h`> H߿|G0߿G? ,Ϡ|/_˗/_>'0_>G0_| ˗/A o@$X`> ˗? 4xaB 6tbD)G1_Ŋ+BWbE* ̗O`> W`+V\b|+VXbŊ+W1_Ŋ+BWbń*̗/_W`+V\b|+VXbŊ+W_+V|bŊ UX1a+VT|*VXbŊ+V|'P8`A !B"̗o`|O`>C/|!D_>"D/Bˇ`|"D!‚"'0_|{/|˗/|/_| /_|˗/|˗O`/_|/_|˗/߿|/_>/߿|;oa| ̗/|`|˗/߿0#G? W` <0… :|1ĉX0_E ̗_ '0| '0|/߿| '0|c!|/߿_/߿/߿? W_|O`> ̗/| ̗O`>_|/_>`O`| '0|o`>/| '0|/_,X`A'p "Lp!ÆB(q"*̗"|/|O`>o`>'0|̗/_>70_'0| 70| 70| ̗_| '`>/߿G߿|?'p`̗o| /| 70߿| '0|O`>O@$(0_ /,h „ 2l!Ĉ'R"|/_|70| '0|/|O`>'0_70_| '0| '0߿| '0|8_'߿|/߿߿|/߿'P`/|/߿| 70|O`>O`>_| 8p`>$X'p "Lp!ÆB(q"*&WQ |@_oO|| H`7`>߿|߿|߿|7? W0_'0_>/| O?| o'P /߿߿߿|/߿_ o`>$/_ ,/,h „ 2l!Ĉ'R|!'0_Ŋ U0_>Xb|+VX0_EUXbŊ+V/_Ņ*B̗/_XQa|1WbE*VX` XbŊ+VX_ UXb|+V$bŊUX"|WbŊ+VX|XbE*VH0_ŊXbE*6̗bŊ+VXb*:WbŊUXq`+WbŊ0_+VXbŊ0_Ŋ+WbE? 4xaB -\p… [p!|.\p… .\p… .\(0… [p… .o… *̷p… [p… "̷p‚-\p… .\p… .\P` ̗o… .\_ .\0… .To… .\x0… ˷p… .\p… .\pB.\x0… .\p| .\0a .\0… .\` ̗o… .\p… .\p…-\a .\p <0„.\pa| .\pB.\0_ .\p… .\p…  ̷p„.\p… -\pB.\p!| .\pB.\0_ .\p… .\p…  ̷pB.\p… -\pB.\p!| .\p‚.\0_ .\p… .\p…  ̷p….\p… -\pƒ.\p| .\p‚.\0_ .\p… .\p…  ̷p…-\B -PBO@ DP| .\` .\p!| .\/_ .\p… .\p…  ̷p…-\p… [p…-\pB.\p…[pB-\p… .\p… .\P` .o… .\0… .4o… ̷p… .o… ˷p… .\p… .\pB.\` .\p!| .\` .\X0… .\P` .,/… .\p… .\p…  <0!|*TPB SPB )TPB*TPB)TP|*TPB *TPB *TP| *T_> *TPB*TP| *T0a> *TP!| *T_| *TPB *TPB *T_> *T(0B *TP| *T0a> *T0B *T`> *T(0_> *TPB *TPB *T/B *OB *T_> *T0B *DOB *Tx@8`A&D/B *TPB *TPB *OB ̧PB *T/B *DOB "̧PB *4OB ̗OB *TPB *TPB ˧PB SPB *̧PB SPB)TPB SPBSPB *TPB *TPB)TPB*TPB )TPƒ*TP| *TP‚*TP|*TPB *TPB *TP| *T`> RH!J| H*o…  ̷p… ̗o…  ̗o… .\p… .\p…-\p.\p…-\p.\p| .\p| .\`| .\p… .\p… .o… ̷p… .o… ˷p… [p… [p[p… .\p… .\p| .\`| .\p| .\0… .̷p… ̷p… ˷p… .\p… .\pBO@ DP| .\p| .\0… .̷p… ̷p… ˷p… .\p… .\pB.\p!| .\p| .\0… *̷p… ̷p… ˷p… .\p… .\pB.\pa| .\pa| .\0… *̷p… ̷p… ˷p… .\p… .\pB.\p| .\pa| .\0… &̷p… ̷p… ˷p… .\p… .\h| H*\o… .Do… [p„.\p.\p|.\p… .\p… .\(0… .\/… .\0… "̷p…-\p…-\p…[p… .\p… .\p| .\p| .\p| .\0… "̷p… ˗o… ./… .\p… .\p… [p… [p… [pB.\` .\_ .\`| .\p… -B -B -@O@ DPB2dȐ!| 2d80C ǐ!C cȐ!C cȐ!C 2dȐ!C 2dx0C 2\/C 2T!C cȐ!C2dȐ| 2dȐa| 2dȐ!C 2dȐ!C cȐ!C cȐ!C 1dȐ| 2d(0C 2,!C 2/C 2dȐ!C 2dȐ!Ã2dȐ!C2dȐa| 2d(0C  ǐ!C cȐ!C ǐ!C 2dȐ!C 2d`> 2d <0…1dȐ| 2d/C 2$!C 2/C 2dȐ!C 2dȐ!Ã2dȐ!C2dȐ!| 2d/C ǐ!C cȐ!C ǐ!C 2dȐ!C 2d`> 2dȰ`> 2d0C cȐ!| 2dp`> 2dȰ`| 2dȐ!C 2dȐ!C cȐ!C cȐ!C1dȐa> 2ǐ!C cȐ!C ǐ!C 2dȐ!C 2d`> 2d`> 2dx@8`A&OB SPB ˧PB *L/B *TPB *TPB *OB *T0B *Th0B ̧PB)TPB*TPB ˧PB *TPB *TPB SPB *OB *4OB SPB*TP| *TPBSPB *TPB *TPB)TPB  ̗OB *$OB SPB*TPa| *TPBSPB RH!RH!RH!RH <0… kذaC6lh0_Æ kذaÃ6lذaC5lذaÆ 6lذaÆ װaÆ װaÆ 5l` װaÆ5lذaÆkذaÆ 6lذaÆ 6aÆ 6DaÆ kذ| 6,aÆ k/_ ̇0_| 6D/_Æ 6lذaÆ 6lذ| 6lذa| 6l0_Æ kذa| 6lX0_C ̗oa6l0_ 6lذaÆ 6lذaÁ6lPC )P>$XA ̷p….\0… .oa|'0|/_|˗O`| ./߿| ̗/_XbŊ+VX_W1a U(1_Ŋ*VW"|/| '0_/_XbŊ+VX_̗/_>'0_|˗_|˗/߿|嫈0_ŊUb|+.W1_ 70_|O`U/_Ŋ+VXbŊU/_> ̗|˗/߿_|/߿|˗? 4x_|"D!B"D|"D_>"D`>"/| ˇ!B <0… :|1ĉ80_ /߿߿|߿|O@ !B"D/B"!Bˇ!Ḃ!B˗|"D|8`A&TaC!F8|_| '0_| '0|˗O` U0_ʼn*NW|+V0_+VXbŊ嫘/_|˗O`|O7P  /_|'`>/? $/,h „ 2l!Ĉ'R"|'p "$O`K0_„ &L/_„  ̗0a„%L0aB%L_| '0|O`| '0|/|/a|8`A&TaC!F8|/_Ŋ(0_Ŋ Ub|+W1a| '0|O`O`0? ̗? 4xaB 6tbD)W1_>˗/߿|/_|'`>G߿࿁'p| H&̧Pƒ*Tx0B "̧P/|˗O`| '0_o`> ̗O`>SH0_> *TPB *TPB *T/B(߿| O|/߿/߿7߿|_'_'p|8`A& *QDU̗`> /_>o`>/_| '0| 7p@8`A&4OB)T`> */߿| '0|/| '0|O| *T_> ̧PB*T`> *TPB ˧PB *TPB *TPB S_| ̗/_/_>O`| '`>_ /߿8| ,X` +X` W` W` ,X_ ,X| ,/| '0_ $/,h „ 2l!Ĉ'Rbň*V4bE*:Wa1_|EWqa|+VXbŊ+Wb|+W|0_ŊU/_|˗O`| '0|/_|/| ̗/_˧0_+VXbŊXbŊUx0_ņ*6W|%/_/|O`>'0| '0_O`| XbŊ+VX_+Vh0_ŊUl? 4x`>"D(0_>"D/߿|_O`'0| /|˗|8`A&TaC!F8|+VX` 0_E*VW"|?'_߿|/߿__'? <0… :|1ĉXbŊUX0_E*2Wb/|/_| 70_|(?o߿8`| H*\ȰÇ#JH_+V0_ 櫸0_Ņ*RW|U0_+VXbŊXbŊ U80_Ņ*.Wqb+bEUXbŊ+V/_Ŋ+VdbŁ**WQaUXbEUXbŊ+V/_|*VX|+ WQa UbŊ+*O@$XA .dC%N/|UXbE*Vb|(1_Ŋ+VD/_UXbŊ+V/|*VX|+W1a UbŊ+̗/|*VXbŊ+Va|*VXb|+WaUbŊ+̗/_|*VXbŊ+Voa|*VX|+櫈0_E*>̗bŊ+̗a|+VXbŊ+0_|+VX_UD|XbŊ0_+VXbŊ*| H|'p "Lp!Æ 9t0C:|:tСÃs80_>:tСC:t| СC:,/C 9ta|СC:,/_>sСC:tСCa|:tСC9t0Æ6С|:tСÁs0_>:tСC:t|˗C:t(0C 9la|СC:/C9tСC:tСCs0_|:tС|*P>$X`|, ;xW`UTbŊ˗"|*VXbŊ+V|UX|80_Ł*&̗bŊWqb|+VXbŊ+Wb|*VX`U|XbEX1_+VXbŊ? 4xa|%L0a„ &4/a„%LX0_„%LP` &L0a„˗0a„ O@ DPB >QDUh0_+V/_E* WQ`UX|Uh0_+VXbŊXa|*VX_ IO@8`| ,Xp`>$XA .dh0_| 6d/_Æ 6lذaÆ 6lذ| 6l/_| 6lذa| ̷`>'p A ?#H AO@ DPBkذaC5lذaÆ 6lذaÆ װaÆװaÆ װ|װa|k_ 6lp`|6lؐ`| 6lذaÆ 6lذaÆ5lذ|5lذaÆ5lX0|k |'p  ;x 2d0_>cȐ!C!ǐ!C ˗!C 2$/C 2dȐ!C 2dȐ!Ã2dȐ!CcȐ!C1!C g0C 2 2d`| 2dȐ!C 2dȐ!C cȐ!C ˗!C 0C 24`> 2dh0_> 2dPa| 2dȐ!C 2dȐ!C cȐ!C ˗!C ̗0_> 2d0_2dȐ!|1dȐ!C cȐ!C 1C 1C 1C? 4xaB &̗/_Æ *w0_Æ 6 '0_|6l/_ 6lذaÆ 6lذaÁ6lذaÆװaÆװaÆ kذ!|6L0|'? <`| H*\ȰÇ#JH_+Vt/_Xb|+̗/_Ň˗_|˗o`|Wqb|+VXbŊ+WbŊWb|+Vb(1_˗_|̗/_XbŊ+VX_+V/_ŊUXbW"| o? <`| H*\ȰÇ#JH_˗ob>bW|+V(0_EXQ`|˗o`|˗_|'WbŊ+VX|/|U|UbŊ 櫸0_+VX0_+VXbŊ壘/|'0_|˗/|/| ̗/_'0_E0_Ŋ+W`|*VX|*VXbŊ+Vb| ̗_>O`>O`>/߿߿| H˗/a„%L0a„ &L/aƒK0a„(? 4x_>̗? 4xaB 6tbD)G1_>_>O`>o`/_|U/_ń*VXaXa|Xa|+VXbŊ+G1_|O`| 70| '0|O`>bh0_Ŋ+&1_|+F̗O`| ̗_| ̗/_> ߿|O@  <0… :|1ĉ0@7߿|߿O|_7P8`A&/_> SPB *TH0‚)TPB/߿|O` '0| '0| ˗OB *TPB *TPB ˧PB *TPB˧0a> *TPB)/_> *T`|/_| '0_|O`>S`| *TPB *TPB *T_> *TPB *L/_>)TPB *4a|*TPƒ˗/߿| '0߿| '0| '0| H|8`A&TaC!F8|(? 4x!|70_„ &,/_B&L0a„ &D`|&L0a„(߿߿| /߿_ O@  <0… :|1ĉ嫘/|*Vw0_Ŋ˧0_Ŋ+:/_|+V/_Ŋ XbŊ+VX_ ̗_|˗/|/_> ?_ /߿G? 4x|̗0a„ &L0a&L0a„  ̗/a„ "̗? 4xaB 6tbD)W`>_'_߿| /߿_/߿/,h „70B *TPB*TPB *TP!|*TPB *TPB *TP| ˗`> /_>o`>/_| '0|  <0!|SPB *T_> *TP| ̗/_>)TPa|*TPB *TPB *TP| ˗`> '0| ̗_>O`| ̗o`>O`| ̧PB SPB *TP`> *TPa|/|˧PBSPB *TPB *TPB)T/_˗/| ̗/| '0_|0 /߿߿| ḨPB *TP| *TP‚G0|*T`| *TPB *TPB *T_> *T0B *TPa| *TPB ̧PB *,/_>/B ̗OB *TPB *TPB ˧PB SPB *$OB *TPB*TPBo`|SP‚)TPB *TPB *TP*TPB *TPB*TPB *$OB )B/߿O` O@ D0_>$XA .dC%N/_Ŋ+V1_Ŋ+VbŊ ˗o |o@$XAO@ DPB >QDUXbŊUXb*VXbńUXbŊ+V/_Ŋ+V1_Ŋ+VbŊ+VL/_Ŋ+VXbŊUXbŊUXb*VXbńUXbŊ+V/_Ŋ+V1_Ŋ+VbŊ+VL/_Ŋ+VXbŊUXbŊUXb*VXbńUXbŊ+V/_Ŋ+V1_Ŋ+VbŊ+VD/_Ŋ+VXbŊUXbŊU$0@ HP`>70_|'P ? H!D!B"D!B̗? 4xaB 6tbD)WbŊ+BW`|S/_|/߿|'0_> ̗O`|嫈0_Ŋ+V0_+VXbŊXbŊ!H0_>˗/| ̗_|G0|'0|嫈0_Ŋ+V0_+VXbŊXbŊ!H`>߿| ? o|8߿|? H!D!B"D!B̗? 4xaB 6tbD)O@ DPB >? 4H0_`|G0|`>˗O`|O`|/_E*VXbEUXbŊ+V/_Ŋ+V1_EG0_|(߿o߿'p  O@ DPB >t/D!B"D!B"D!Ba>!Ba>!B"DA"D!B"ā B"D"D"D!B4/D!B"D!B"D!Ba>!Ba>!B"DA"D!B"ā B"D"D"D!B4/D!B"D!B"D!Ba>!BQa>!B"ăA"D!B"ā B"  <0… :Ç>|a|>|Ç>||>|Ç{ÇÇ>|0_>|Ç>|_>|Ç=|Ç{Ç>|/Ç>|Ç>|/Ç>|C>|Ç=||=|(0_|̗Ç>|Ç>Ç>|a|>||>|0|>`{Ç>|Ç{Ç>|@8`A&TaÆ:t!| O`| ̗/_>0߿ O'p "Lp!ÆB(q"*VXbE*VXb+2̗/| '0_'0|`/_|*VXbŊ+VbŊ+VbŊ'X|O`O``/a|+VXbŊ+WbŊ+NWbŊUXqa| '0|O`| ̗_ O`|%̗b+VXb*VXbʼn*VXQb+2̗/_'0_|/_|˗O`>(0@O@ <0… :|1ĉ/_|*V4bŊ/_Ŋ+FWbŊWb|+VXbŊ+W1_>UX0_Ŋ˗`+VbŊ +b|*VXbŊ+Vb| ̗/|/_| 70_|/_|˗/|U(1_|UX"|*V`>@˗o|/,h|8`A&TaC!F8|;O`| 70| 70|/_>X1b| UX|Wbń ̗_|'0_> ̗O`|WbŊ+VX|#O`o`>o`> ߿| <0[(0… .\p|˷p… ̗O`|#O`|'0_ ˷p… .\p… .\pB&̗/|/߿| '0߿| 70|O`.\0a|̷p… .\0_|-\p… ߿߿ $XA .dC%N/_E ߿/߿ 70߿/߿߿| <0!|)T/B *TP‚ ̗OB *$/_|+/|/B SPB *TPB *TPB)TPB *TP|)TH0B *TPB̗/B *T/_ '0_/_|S0a| *TPB *TPB *T_> *TPB *̗OB*TPB  ̧0a|*TP!| 'p߿(? 4X0_>$XA .dC%N/_Ŋ+Vd/_ UX"|˗bŊ+2̗bŊ+VXb*˗/_ U0_|XbE*̗/_Ŋ+VL/_Ŋ+VXbŊU̗O`|X1a|*FWbŊUL/_Ŋ+V'0_o`>U/_ŊUX|˗bňWb|+VXbŊ+G1_>_>|߿70,h |!D!B"D!B"$!B˗!B˗/_>'0_|'0_|'0߿|C`| H*\ȰÇ#JH_>/|O`/| /|Wqa|*VTbŊU(0_|!'0| '0|'0|˗O`>UXbŊ+V/_E ߿/߿߿7O@ /_>"D`|"D!BC!BC!B'0| G0_ ̗/_>/_|"$/,h „ 2l!Ĉ'RbŊ˗bE WbŇ*VL/_ '0| G0_70|70|*VXbŊ+VbŊW"|UXa˗"B /߿7?'`>'@ H`|8`A&TaC!F8|+VX0_|+Fw0_ŊX1b|*VX`|+VXbŊ+WbŊW| X|Xqb|*VXQ`|+VXbŊ+WbEXb>*VX0|+V̗bŊXbŊ+VX_+F̗/_ŊsbŊWbX|*VXb+VbŊX"|Xb>*V80_|+V|/_Ŋ+VXbŊUXa|'p "Lp| cȐ!C)ǐ!C ˗!C 2/C 2dȐ!C 2dȐ!Ã2dȐ!|1dȐ!C&̗!C _> 2d0_| 2dȐa| 2dȐ!C 2dȐ!C cȐ!C ǐ!C c0_> 2$/C2dȐ!|2dȐ|2dȐ!C 2dȐ!C ǐ!C ˗!C 2/CcȐ!|ǐ!C ˗/C 2QDU0_|+V"| 8p 'p@$ A $? 4xaB ̗/_Æ ˗aÆ 6lذaÆ 6lp` .̗aÆ 64aC&O@$X`> ,ϠA 4hРA ̗/A 4hР|8`A&TaC!F8|+̗/_Ŋ+WaUb|+V/_|+̗bŊ+VXb*V/_+V|80_ń*VXq`|*V/_Ŋ+VXbŊU/_+V,| 80_E*VX`|+WbŊ+VX|#˗bŊ WaU$|+Vh0_|%WbŊ+VX|WbŊU"| 櫸0_Ŋ+"̗/_ŇUXbŊ+ $X_|8`A&TaÆ:lϡ:ϡC:tСCP`|:tСC:tС˗ϡC:t0C9t/C9t0C:ta|sСC:tСC˧0_|:tСÄ9t0C9t(0C 9tСC˗oa|:tСC:tССC:\ϡC9t(0C9t0C:tpa|СC:tСC:`|:tСC  <a ̗0aB&LP` &L0a„ &/_'p "Lp!ÆB(q"˗bŊ+W|櫨0_EUXbŃ/_Ŋ+VXbŊWbŊXq` UT"|+VX1a|UXbŊ+V/_Ŋ+VTbE*.WqaUXbEUXbŊ+V/_Ŋ+VLbE*2WqaUXbńUXbŊ+V/_Ŋ+VDbł*2WaUXbEUXbŊ+V/_Ŋ+V|Ç>|_>||>C>$Æ>|Ç{Ç>|Ç{Ç̗Ç=|H0Ç=|0Ç /|>$/Ç>|Ç>|/Ç>|p`a||"̗o`|=|`|>|Ç>||>|C>|h0Ç=|X0Ç=|x0_ ̗/|/_0,h „ 2l!Ĉ'RbŊ+Wb|0_Ŋ`>?'_>$XA ˧PB *TPB *TPB SPB *T`> *T(0B SP| *Tx0B 70_>/_|)TPa|*TPB *TPB *TP| *TPB ̧PB SP| * *TPB *TPB *T/B *TPB)TP*Tx0B SPB*T(0_ ̗/˗O`| H̗OB *TPB *TPB ˧PB *TP| *Tp`> "̧PB*Ta> *TPB ˧PB *TPB *TPB SPB *T_> *TH0B SP!| *T0B *TPBSPB *TPB *TPB)TPB *TOB ̧P„*T0B &̧PB *TPa| *TPB *TPB *T_> ˗OB? 4x|&L0a&Lp` &/a„ ̗0a ? 4xa‚)TPB *TPB *TP*O`| *OB)TPB*T0B SPB)T0_ SPB)TPB *TPB *TP*/_| ̗/_>70_|8? 4xa>"D|"D0B"̇!Ḃ!B̗/_70|C!BO@ DPB >QDU/_O`| ̗_> 70_Ň*V|"|'XQa| 70_>/|/_ŊXbŊ+VX_O`o`o`U1_E*RW| G0_|O`  <`| H*\ȰÇ#JH_> '0| ̗_>'0_>0_ŊU"|+2Wq`| /|/|+ ̗bŊ+VXb*˗/|/_|˗o`|/_Ņ*Vb|+Xa0@_O@ D0_>$XA .dC%N/_E X`%X1_Ŋ*VlbŊWbŊ+VX|+bE*Vb*Vbņ*VX`|+VXbŊ+W1_̗/_  "D80B"!B"D!BC!"D0_>$XA .dC%N/_|#/|'0_XqbXQ`擘O`|櫸0_+VXbŊ壘/_/_>G0|'0_|*Wb|+ W|+>1_/_|˗o`|˗_|**̗bŊ+VXb*O`|̗`>'p gРA 4h| 4hР 4hРA4hРA ϠO`/|/߿|4hРA'p "Lp!ÆB(q"*o` G0|O`|QWb*VbŁ*V/_|o`_#|*VXbŊ+Vb/|'0_> /_>IWb*V$bE*Va| '0|O`| ̗_>*.̗bŊ+VXb*#/_> 'Po  gРA 4h`| 4hРA 4hРA4hРA 4Ϡ|/_|˗O`| ̗/|3hРAO@ DPB >QDUXQb+ Wb|+W| +bŃUXbŊ+V/_Ŋ#X|+Wb|+NWq`*VQDUXqa+W|+Wb*V0_+VXbŊX|+V$XA .dC%N/_Ŋ X|+*W|+V,bŊXbŊ+VX_+WbE*V\bŅ*VX0_Ŋ WbŊ+VX|+V/_ŊXqaX|+V/_Ŋ+VXbŊUX_+2W"|+2WbE*V(0_+VXbŊXb+6W"|+2WbŃ*V/_+VXbŊXb+6Wb|+2WbEUH1| H*\ȰÇ#JH_'X|+6Wb|+VLbʼnUXbŊ+V/_ŊUXaXa+*W|*VXbŊ+Vbň*V0_ŊU0_ŊX1b|+VXbŊ+W"|+VbE*VtbŊ U1_+VXbŊXa+BW|+>WbŅ*V|/_Ŋ+VXbŊU0_Ŋ#XaX"|+:̗bŊ+VXbO@ D0a| *TPB*TP!| *Ta> *TPa| *T`| *TPB *TPB *T_> *T80B *TP| *Ta> *T0B *T`> *TH0_> *TPB *TPB *T/B *OB *TP`> *T0B *LOB *Th0B */B *TPB *TPB *OB ˧PB *T80B *LOB &̧PB *<|8`A&4/B *TPB *TPB *OB SPB *OB *̧PB SPB "̧PB SPB *TPB *TPB)TPa| *TPB)TPB*TP| *TP„*T0a| *TPB *TPB *T_> *DOB *T`> *T_> *T_> *TPa| *T0_> *TPB *TPB *T/B ̧PB RH <0B.\p| .\p.\p`| .\p… .\p… .o… [p… "̷p… [p…-\p… [pB-\p… .\p… .\P` .o… .\0… .̗0!|8`A&TaC!F8| {/|Cbň/|!X|'0_=W`|+VXbŊ+Wq`> ̗_|˗/@O ,h B̗`|/_|'0_|/_ K0a„ "̗0aB ̗_|˗/߿|/_> ߿_7? 8p <0… :|1ĉ/_ ̗/_>/| /_>˗/|*F1_|˗O`>/|W`+"W!|? /߿/߿߿| ߿|'_> A ̗? 4xaB 6tbD)W1|/_|/_| ̗/_>'p`>$XA%L/|O`>˗/|&_>'p| 80A /,h „ 2l!Ĉ'Rb>˗/_o`˗o`>'0_E70| '0| '0_|*Wbń*̗`> /| ̗_>O`| /_>Sb|+VXbŊ+71_E 7P Oo`O@ D(0_ƒG0_/? '@$X|$XA .dC%N/|+̗o` 80_ X|+Vb|$WbŊ+VX|Ux0_>*V$|*V4bŊ UX_ E̗bŊ+VXb 8`>8`| W` ,Xp` ̗/_ ,(0| ,X0_/_ 'P '0A  A /_| 70,h „)4/B *TPB *TPB *Oa| ̗OB)TP| '0_>'0B)/|*̗O|  ̧Pa|ˇ0B *DOa|*TPB *TPB *TP| S`|˗O`>˗O`>'0|/_|˗O`70_|Sx0_>˗/|/_|˗_>70_| ̧_|/_|˗(0_>/߿|'0_|8`| ,X0|˗_|/_'0_| ,X`,H0_>$XA .dC%N/_| 'P_/߿|___/߿8p`> //_>'0| '0| G | ̗O`| ̗/_>GP |7߿|_'p ,X`>/߿|'0_>O`| ,X`A /,h „ 2l!Ĉ'Roa|W0| 70߿|/_|O_> /| 7p|8p`|/߿|8_> ̗/| 70|o/߿|0'p`|'0|˗o7po| /| '0|˗? 4x|  <0… :|1ĉSb| O`>/_>_| '0| /| ̇0| ̗O`|˗O`>_| '0|1̷0_>'0_|`|˗_>'0_>* ̗O`| ̗_/|˗O`|%[/_Ŋ+VXbŊ%WQ!|7߿? _/߿7߿|߿'p| $H`>'__߿'p A /_|˗O`| W| '_G? ϠA˗o`| ̗O`>O`>gРA g`| H*\ȰÇ#JH_>*VW|;bʼn 0_Ŋ櫨0_Ŋˇ0_+VXbŊ;b*V\/_|UH1_|X|Xb|XbŊ+VX_>*VX|+VbŊUX"|XbŊ+VX_*VX"|+VbŊUX"|XbŊ+VX_>*VXb|+VbŊUXb|XbŊ+VX_*VXbA8`A&T| 6lذ| 6lذaÆ ̗aÆ 6lذaÆ 6lp`>6lذaÆ kذaÆ kذaÆ kذaÆ 6O`| 6lذaÆ 6lذaÆװaÆ 6lx0_Æ 6l80_Æ 6l80_Æ 6lذ|kذaÆ 6lذaÆ 60 <0… :|1ĉ+Z1ƍ 8`A&TaC!F8@$XA .dC%NXE5nT <0… :|1ĉ'p "Lp!ÆB(q"Ŋ/b̨qB$XA .dC%NXE5nG!E$YI)UdK1eΤYM9uOA%ZQI.eSQNZUYnWaŎ%[Yiծe[q%;;PKvW?z:zPKFJOEBPS/img/dcl_stmt.gif$GIF87aP?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,P H*\ȰÇ1bĈ#F1bĈ#F1bĈ#F1bć H 'p "Lp!ÆB(q"Ŋ/b̨q#ǎa|X0_>=zѣG=zQc>/_|˗O`|'pO ,h „ 2l!Ĉ'Rh"ƌ7r0_˗_|3/߿|˗_>/|ѣG=zѣG3W0| g0|O`'0A$XA8`A&TaC!F8bE1fԸQ#|'P`o|˗/_|_>$XA <0… :|1ĉ+Z1ƍ ̗`|˗O`>70߿|/_>DZa>9rȑ#G9r` ˗/߿|;O |_߿8`A <0… :|1ĉ+Z1F HA HP`|+X` ,/_ ,X`8`A&TaC!F8bE1fx0| ̗!|'p w  <0… :|1ĉ+Z1ƃ.c`|!˷Qb7nܸqƍ7nx0| !̗o|moƍ7nܸqƍ7w1| ˷qa|6N̷qƍ7nܸqƍC/@߿| HP`8`AO@ Dp`>$XA .dC%NXE5̇0_co|3۸qƍ7nܸqƍˇ0_|G0|7noƍ7nܸqƍ7̗`|w0_|mܸQb7nܸqƍ7n08_|Gp |$ <0… "O@'p "Lp!ÆB(q"Ŋ/b̈0_OOGP`>$XA .da>9tСC:tСC:tСCC_> 70|СC:ϡ|:tСC:tСC:tСÃ)g0|0B O@ 'p "Lx? W`A8`A&TaC!F8bE1foaK08 AO@ D|'p | $/,h „ 2l!Ĉ'Rh"ƌ-w1|g0_| ˧Q|!1F5jԨQF5B̷0| ̗/a| Ө`|拘OF5jԨQF![b> ˷0_>̧a ;/|iԨQF5jԨQ#| ]0|w0_˘`1F5jԨQF5B̷`> 4H? ̗`/_/_>/_#o`/߿|/_|/_>W`A8`A&TaC!F8bE1fO|k/|3/߿|˗/|+/߿|˗_|/_|/_| ̗`>4jԨQF5jԨb>/|w0|˗`>#/߿| ̗/|'0|曘OF5jԨQF!Ө1_|8P '0_˗/߿|O`|'0? _| H`| H*\ȰÇ#JHŋ3̧Q|̗`>/_3/|'0__|/|5jԨQF5j1F3`|˗`>˗O`|g0@ ߿/߿'? 4(0,h „ 2l!Ĉ'Rh"ƌi80_| ˧Q|.ӨQF5jԨQF4ja|0 HCa>$XA .dC%NXEӨq`| C/FØOF5jԨQF!Ө`| K/F˘OFiԨQF8`A&TX? W` ,X`+(0_| ˗` ,X`+X`,(`> 4xaB H|,h „ O@8`A&T0,h|"D!Ḃ!B"/_|˗a|C!B˗/BCH0B"DX0BC!B"/_>!D!Bˇ!ƒ"D!B!$!B"D8`>'p 8`A&T a ˗/@ 'P`|'P࿁(0O@ DPƒw0_|8? o/߿߿|_>$X+O` `>70|C80,h „ 2l!Ĉ-g0|3o` G0|%w0|I '0_> '0|ITO` o`>#o`|˗0|I(QD%J<`> _`|/_ g0_|88߿ 7?'0_|8߿߿|O| 7P`|/@ ̗O`o`'p /|#`>'0_|!`>'p "Lp!ÆB(1|70߿|G0__/_|_/_>_ /_;/߿|˗_>/|/|G0_#`|``>'p `>߿'p A O| 8`> 4xaB 6tbD 'p`'P| o|0@ O@@ o`|˗O`_|'0߿|'0|_ '`>'p|`| G`> _ _?8P ,hP`|/|w_|wP`8`A&TaC!F0_>`>#0@_8p`>GP`|/_|0@__8_>˗/߿|`>߿8`>'P//߿| O`| o|8p@8_ 70@/| ̗/߿|7_>$XA .dC%:/|`/| /_|˗`70߿|_>/| /|_>/|/_|o`| G0_|O`70|M$O` ߿#A ̗/_ o`>70,h „ 2l!Ĉ`| Oo_ ? '0_'`> 7߿|߿/? O |_߿|_>̗/_/|'P|@/߿'p`8`A;/E8? 4/_(RX0Ņ(R"E)RH"|)6̧0_|)R4/_(RX0Ņ H*, <0… :|1ĉ8`A&T'p "Lp@$`> 4xaB 'p "Lp!ÆB(q"Ŋ/b̨q#ǎ? )r$ɒ&OLr%˖._Œ)s&͚6o̩s'Ϟ> *t(ѢF"Mt)ӦNB*u*ժVbͪu+׮^ +v,ٲfϢMv-۶n+w.ݺvͫw/߾~,x0†#Nx1Ǝ/;;PKsU)$PKFJOEBPS/img/lobwri.gif: GIF87a?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU, H*\ȰÇ!1bĈ#F1bĈ#F1bĈ#F1bć H 'p "Lp!ÆB(q"Ŋ/b̨q#ǎ`|QD-^ĘQFG0_/_>/߿|_|+/G=zѣG=z1_>70| ̗O`>˗O`yѣG=zѣG(߿O'p`>˗/|O@ O@ Dx? 4xaB 6tbD)VxcF-/|˗O`>70|˗/|0G9rȑ#G9rh0| 'p@O |߿|8`A <0… :|1ĉ+Z1F HA HP`,X` /_ ,X | H*\ȰÇ#JHŋ3j `>8`A;xO@ DPB >QD-^ĘQ|1w0_(1ƍ7nܸqƍ7n˗o|6N̷qƍ7nܸqƍC/@O|oO@ D/_| &LP`>$XA .dC%NXE5̇0_>cO!|,h ‚ H <0… :|1ĉ+Z1ƃ˗o`>81ƌ6nܸqƍ7nܸqc|̗_#`7J̷qƍ7nܸqƍ w0_C`>6n(1ƍ7nܸqƍ7fO@ `>8 A$XA .d!|, <0… :|1ĉ+Z1c|g0_C`>4jX1|4jԨQF5jԨqb3`>#`>5V1F5jԨQF5F̷0| -O@$X |,h „8| /,h „ 2lP!|,h „8`A&TaC!FToa>1̗`>'p A  <0@ O@$H_>$XA .dС|>Ç>|Æ{0|g0_| ÄC|>|C>|80Ç>|Ç -a>˗0_>=|a|{(0Ç>|PaÇ>|a| =Da>-̗a|=|H0_|̗`=|Ç;/|/_|(_o`> <0… :|1| I,a1̗`|5'ag0_|%J(Q|o``| '0_$J(QD%˷`> 4H? W0_| ˗/| O@ 70߿| ̗_/_|˗/ ̗o  <0… :T`|_+/| W0Ç>|Ç =|`>5̗o`>/_|'0_|O`˗_˗/߿|˗O` {80Ç>|a /|70|/|Ç>|a|>,/|#_70_|/|o`|/_>'0_=|Çg0_˗/|O |/߿|_>  <0… :|1|%>̗/_ (?/|(?O`|'0? _o`>$X`>$XA .d@ /80@'0|'p@$XA .dC(Qb˗`>/_̗O`/| /_| ̗Ob|%J(b|+/|g0_|O`|!̗OD%J(1a>%g0|`>˗O`|w0@ ߿/߿'? 4(01bā5w0_8? 4x`|"̇!B"D!B!!B"̇p`>$XA .dCE`| C/_Ĉa#F_"Fta#F1bD"FH0_>%̗/_Ĉa#F_"Fta#FT0 <0‚ HP` ,X` ˗/_A+X0_| ,X` ̗/_ `A H8`> 4xA$(0_,X` `A8`A&Ta> 2Ta> 2L/_|˗|cȐ!  4`|g0B"̇`>8`A&,O@ DPB2dPa1dȐ!C 2dȐ!CcȰ`>2dH0| 2dȐ| 2dȐ|(߿|o'p`|˗/|o'p "Lp!ÆB0|̗/|;`|o'P`  <0…1dȐ!Cg0|70|o`>[!C 2dȐ!C 2̷0_| 70| 3`|/߿|70| -ǐ!C  ǐ!C '0_|'0|70߿|˧0|1dȐ!C 2dȐ!C!'0_|'0| O`˗/߿|/_Ko`2dȐ!ÁcȐ!CW0|#/a|+_>O| H*\ȰÇ#J̇0߿| W0|G0߿|/߿| /|%G0|$J(`$J0_ ?8? ˗/߿| A˗/_>$XA .dC% ̗/_70_|(? /_> /߿@ o|O@ DPBW0_Æ  O@(0'07p| _O@ DPB >QD o` 70 (?/_| /|8p |,h „ 2l? 4xaB W0| W0|O`>Oa>.\p… .\p… `>'0|/|˗O``[p… .o… *'0_A '߿ o`> ̗/_(| /| H*\ȰÇ#JtO`'0_|˗/| w0|/_'P ? 4xaB 6tbD$JH0D%J(QD I\`> (QD%J80D (QD%J(a> 'Q"|%J(QD(Q"|%J(QD%2'qa>$J$OD%J(Q|%J$OD%J(QD$.g0DI(QD%JODI(QD%J0ą (`>%J(QD8`A&TX? 4xaB 6tbD'p O@$XA8`A&TaC!F8bE1fԸcGA9dI'QTeK/aƔ9fM7qԹgO?:hQG&UiSOF:jUWfպkW_;lYgѦUm[oƕ;n]s8`AO@ DPB >QD-^ĘQF+0G=zѣG=z`>yѣG=zѣG 0G=zѣG=z` /߿7 ? 4xaB 6tbD)VxcF9v`O`> ̇0G=zѣG=z` o`| '0|=zѣG=zѣG+_˗`>'P/  <0… :|1ĉ+Z1ƍ;R̗``>ѣG=zѣG=z/߿|/|O`>ѣG=zѣG=v70|70_70|yѣG=zѣGa>=zѣG=zc<"W0G=zѣG=z1_|+ϣG=zѣG=zP>  =zѣG=zc>yѣG=zѣGyϣG=zѣG=zĘ#|=zѣG=z#|)ѣG=zѣG1+0 

/߿@? 4xaB 6tbD)VxcF9vL` '0_| ̇0|=zѣG=z#|̗O`> o`>ѣG=zѣG1+``|!w0G=zѣG=z1_|/@ OO@ <0… :|1ĉ+Z1ƍ;&O| /|#(0߿|$08`A&TaC!F8bE1fԸcDŽ ;O`|'0|ѣG=zѣG=bW0| O|_>| H*\ȰÇ#JHŋ3jȱc|y4`>=zѣG=zc<w0G=zѣG=z1_| ;ϣG=zѣG=zĘ`>ѣG=zѣG=bW0GѣG=zѣG1+ϣ|yѣG=zѣGO@ D(?O@ DPB >QD-^ĘQF;#|=zѣG=zc|yϣG=zѣG=z\0 'p "LX`> O@ DPB >QD-^ĘQF 3`5̗cǎ;vرcǎ;v<`:V0_ǎ;vرcǎ;vX0|+惘cǎ;vرcǎ;v/b H8p`> ? 4xaB 6tbD)VxcF9 1_| K/b;vرcǎ;vQ` X0_|uرcǎ;vرcǎEW0_ǂ拘cǎ;vرcǎ;v/b+/_|O$H| H*\ȰÇ#JHŋ3jQ` ;`| ̗O`拘cǎ;vرcǎ;v/b+/_`"رcǎ;vرcǎ拘`/|w0_|uرcǎ;vرcǎEW0|`| w0_|uرcǎ;vرcǎEO| /A O| `> O@O@ DPB >QD-^ĘQFEW0|_| w0_|uرcǎ;vرcǎEW0A ߿| ߿| /A$H| H*\ȰÇ#JHŋ3jQ` X0_|uرcǎ;vرcǎEW0_ǂ拘cǎ;vرcǎ;v/b:̗0_|;vرcǎ;vر|ױ`"رcǎ;vرcǎ拘`%1_ǎ;vرcǎ;v(0_|8`A'p| $/,h „ 2l!Ĉ'Rh"ƌ7r/bEױcǎ;vرcǎ; 1_NJ"رcǎ;vرcǎ拘c|uرcǎ;vرcǎEױb:vرcǎ;vرcG"X1_|;vرcǎ;vر|u/b;vرcǎ;vQ` 'p O@,XP`>$XA .dC%NXE5n(0_|ua:vرcǎ;vرcG"+| Eױcǎ;vرcǎ; 1_|c/b;vرcǎ;vQ` C/_>0@ o 8p@8`A&TaC!F8bE1fԸ|w0|_拘cǎ;vرcǎ;v/b|W0|/aEױcǎ;vرcǎ; '1|'0߿|˗0|uرcǎ;vرcǎM̗O`> _'P 8p`|8p| H*\ȰÇ#JHŋ3jQ`>g0_| ̗_ H? 4? 4xaB 6tbD)VxcF9 w1|O`|%_;vرcǎ;vQ`˗/|O@  <(0,h „ 2l!Ĉ'Rh"ƌ7rbucǎ;vرcǎ;vbucǎ;vرcǎ;vbucǎ;vرcǎ;vbuob|uH1_ǎ;vرcG.(0_ 'p@$X`> $'p "8p ,0 , <0… :|1ĉ+&g_> YDa| ˗a| ˗Oa>%̗/_|1̗/EhѢE-ZhQb>8`A 'p  ̇`|ˇP`|"/"D`>C/BC|'p "Lp!ÆB(q"ŊYhb)̗/a|C|[/|,"̗ϢE-ZhѢE,ZH1|w0_>; |(߿߿'p`7p@ (0_ 8_>(0_>$XA .dC%NX`>-Z̷0_| 71|+`O`|3`̗`>c/E-ZhѢEgѢE` '0_>0__> 7P`(0|7p`7p`O`|˗/|8O'p "Lp!ÆB(q"ņWbŊ!̗/|˗`'0߿|̗` +o` /| #_| #_>˗_>/_>W0|+VXbŊ+6̗/_+VL/_|s`| O`+/_| ˗/@ ?˗_7P`|80@ o`O`|o|O@ DPB >QD8`A&TaC8 A˗_>?@ 70߿|_| 08`AO`'p| 08`A&TaC!F8|+VX1_|/_O`+/|W0| ̗_g0|k/|̗O`O`|`>*VXbŊ+VXbŊ w0_|/_A ߿|'߿_'P` ̗O`| /_7p`|80_7P`| ̗/_/_> ̗o`>$XA .dC%NXE k/|0w0ƅk/|4̗OF5jԨQF/0_]̗`> ̗oa|H0_>5jԨQF5j̘/|W1_>4.w0_!̗O#|4jԨQF5jԨ1c|˧0_|KO|ˇ0_>Ә/_>5jԨQF5j/_|0_|˧0ƅ˗`|˗c|4jԨQF5jԨQ#A 'p 8?$XA8 |O@8`A8`A&TaC!F8bE1fO|5B <0… :|1ĉ+Z1ƍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3Ν<{ 4СD=4ҥL:} 5ԩTZ5֭\z 6رd˚=6ڵlۺ} 7ܹtڽ7޽| 8 >`> 4x!'p "LX? O| H?$XРA$XA .dC8`A8? O@ DX? 4xaB 6TϡC sС| ˗O`|5O@$X`|'p "Lp!ÆB,/| (@ Hp`|,X`(? 4xaB 6DϡC sС|w0_s0_|:tСCs0|̗/|9t0_|:tС|g0C ;/|С|:tСC60a>%̗Oa|:/C:t0_| `>߿| o|`>_ o? /_ ̗o o7pO@ DPB >(0|'p 8_|/8P`80|(0_| H*\Ȱa|/߿|` 3`> '0|` 3/|G0|9̗ϡC:t|#a;/_|1'0|sСC+/߿|˗_>`> #`|`>`>g0|˗O`>˗/߿| ̗/_|:tСC.̇0_|!g0_> g0_>`>80_|8p _>$XA .dp` _` #_>+_C` #_>/_|/|˗/|`|:tСC`| ̇0|k/|̗_|˗`|O`|˗O`СC*̗`O`>'P (0_ 0@/߿|_(? / 7P`| 70߿| /_|'0@8`A&TaC!w0_C`|/|70|'0_|_>A"D H?/_| 7_O@ o|/߿|o| 08 A@O`>'p|O@$ <0… :t08|?'p@$X`>'p`'P _>'p A H*\0|̗O`|` +/|'0_>'0|G0߿| G0_|_>/_>`2dȐ!C &̗` 70|̗//|70_>˗_> ̗/|̗a| 2dȐ| w0|` #_>`>_/߿_>70|7p`˗o|/_|/_| 7_|? 4xaB 6t0|G0|/_> 70|˗_|g0_| /_|'0_)Ç -!|=|p`>5w0Ç[Ç>|0|3/_| ÁÇ -!|=|p`>1̗`| ̗a>|!| =D`P |'p w``|˗0_|0B$X HP |'p 8@$X`>4h`>380_>3hРA ˗/A4hРA 4h`>4hРA 3hРA gP`| ˗`|4hР|480 4h| 'p@$H`>  g`> gp`|˗`|4hРAgР| 4hРA ,`| 4h`> 4hРA$08 A O@'p ,/ 4h|˗`| ̗/Ag| 3h`| 'p@$H`>8`A 'P ,/A 4hРA 3X`> 4x!'p "LX? ̗/_ O@ O@ 3X0A Ϡ| ̗|4X0_>3X`> 4H? O@$X |,h B H| 4hРA $? 4xaB 6tbD -g0߿|O'p|G|̗| ̗ A8`A&TaC"D B"D!Bh0|˗O``>1̗`|G0_> B"D"Ă B"D!Bh0|˗O`+`>g0| ˗/@? H_>$XA .dC B0|!B"D!BD`> _`>/_|`|O`| 70|!B"D"Ă"D!B| `o` 3`G0_| /_ #`>!B"DQ!|,h „ 2l!Ĉ'R/| o@ 'p@ 70@ O@$XA .dC'p "Lx0B *TPB *TPB g0߿|`W0_>̗/_|o`|̧PB *TPB ̧PB SPB *TPB *TPa|/|̗/_`> '0|/_̗`> *TPB *T`>$XA .dC%NXѢ|3/_|Y̗ŋ/^xŋ/^x"|3/_|嫘/ŋ/^xŋ/^xE.*w0_!̗ob|/^xŋ/^xŋ#滨0|˗0_>]xŋ/^xŋ/^|w0_| 0_|/^xŋ/^xŋ%滨0_|/_| (?˗/,h „ 2l!Ĉ'Rh"ƌ7r,0 QD-^0_˗/_̗_/|˗O`e̘1cƈ5̗`/_|'0_|˗_/_˗O` ̗/cƌ3f̘1cƌW0|;O`'0߿|o`|3f̘1b w0|˗o`_|70߿|`|3f̘1cƌ3f̸`>(0|8_>˗/߿|`>0 < ,h „ 2lx0_|O@ /|0@ /߿|O|``>$XA .dC%NXE ̗`|'0|_>/|1_ƌ+/_|`>/_/|'0_|˗O`70_ƌ3f̘1cƌ3W0A O/߿O ,h B&L0a„ &$`|̗o`>_|˗_|'0? o`߿_>$XA .dC%NXbC$X A$(0_,X` ` ,X` ,X`8`A 'p A W| ˗` ,X`+/,h „ 2l!Ĉ'Rha3/CO@ ̗4;X0|̗|<0 Hp`|,(0_'p "Lp!ÆB(q"Ŋ滘a]/E.^| ̗oa|x1a|]xŋ/^xaC/Eh1ŋ] 4xaA$XA SPB#o`+O| 8p ,0 <0A$? 4xaB 6tbD)V0| ̇0|/x`;o`/| 5w"|]xŋ/^xQa/|w0ŋ/wb>`>+`.^xq`/^xŋ/.̗`| ̇0_|]x|/ |'P`> @ 7p`>$XA .dؐ`>:tСC:tСC 'p A0@O@ H ,h „ 2l`>  08_'0|'p A H*\Ȱ!A$X0,h „ 2l!Ĉ'R0_̗o`>+`>-Z\a|/| ̗O` +`>-Z8`>  A#Hp`> $H| G@ O@ 'p ,h „)<? 4xaB 6tbD)V$oa>1̇0_|˷0_|-*̗/|E0EC/_>g"|YhѢE-Z0|c`| S/E w0_|1ga>˗Ϣ|,Z-ZhѢE[| ̗oa|+"|g0_"拘a>1w0_>,̗ϢE"hѢE-Zha,0|;/|Y`1_| YD0| `W` ,X`  <0… :|1ĉ+̷`> 4H? ̗`|+/_+/_|'0_|G0|'0_˗_| /_|̗`,XP`'p O@+|/_|'0_|˗O`|+X` ,H0_O@ DPB >QD h`>5̗o`>̗_|˗O`|̗_>/_/_|/_>G0|Y0| /߿|˗O`|˗/|#/EIgѢE-Zh|-̗O`| #_70_|/|o`|/_>'0_"ha|3_>/|˗O` gѢ|&hѢE-ZȢ <0|),08_> /_|#(0߿|˗_>'P8߿'p 4X0A 4hР _ ߿O@$XA 'p 'p "Lp!ÆB(q"ŊY0|w0|˗/|̗O`/| /_| ̗|Y(1_>_ ̗/| /|-ZϢE-ZhѢŇ,ZT/|O`/_>/|(_߿|@$XР|w_|'0_|˗O`  C_>"D|"/_| ˇ!B"D80,h „ 2l!Ĉ'RH0E [/|,Z/E"hqb|gѢE,ZhѢE-Z|ϢE)̗/a|-:̗|YH1_> h|-ZhѢń H*,+X` ,X|/_W` ,X`|,X` ,(0,h „ ˗oB[p… [p… .\p… [p…-o…  OO@˗` ,X A O@ w|$JX`>'p 8`A&T 2dȐ!C 2dȐ| cȐ!C 2dȐ!C cȐ!C 2dȐ!CO@ O/_G| H*\ȰÇ#>1D%J(QĄ$J(QD%3`>+o`/|!̷0D%J(QD (QD%J0D%J(Q|g0߿|G0|+_>3OD%J(Q"|'QD%J(qa$J(QD`> G0| W0߿|G0D%J(QD#OD%J(Qb|I(QD%̗ |'߿'p @8P`˗? 4xaB 6tbDW0_|&N8qĉ'̗/_|'N8qD Hp 80߿| o|/@8P |,h „ 2l!Ĉ'Rh"ƌ7O@ DPB >0߿|'0| g0_/_#/bĈ#F1bć"F1bĈ#F/_Ĉ#F1b|O|`8P`| O'P`8`A&TaC!F0ĉ'N8qĈ&N8qĉ8q|'N8qĉ'N8qĉ'N8qĉ'NoĉM8qĉ'N8qĉ'N8qĉ'N8qb'7qĉ'N8qĉ'N8qĉ'N8qĉ&N/ĉ'N8qĉ'N8qĉ'N8qĉ'8q|'N8qĉ'N8qĉ'N8qĉ'N0 <0‚ H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]*|O@'p " O| H*\ȰÇ#JHŋ3jȱǏ(| H |'p O@$8`>  <0… :|1ĉ+Z1ƍ;zh0_|˧0_| ˗oa|$H A $H A/|Ra| S/H A $H A rb|̗a| u̗/| 3/H A $H A 2b|w0_> $H A $H A/|3/|'`>߿|7߿ _>|˗? 4xaB 6tbD)VxcF9v1|O`>˗O`|˗/߿|/_>˗/߿|O`̗Ǐ?~Ǐ?~1|#_> '0_ '0| /|̗`|+/Ǐ?~Ǐ?~c|w`>'p? O/߿8_߿O@ O@ DPB >QD-^Ĉ? 4xaB 6tbD w0|` ̗/|˗O`>_>̗`|+/ĉ'N8qĉ'N8q|'N8qĉ#`> '0|O@࿁O 70|7p`| H*\ȰÇ#JHŋ˘1cƌ3W0_> g0_W0|̗1cƌ3f̘1cƌ e̘1cƌ +/|̗b w0_̗/cƌ3f̘1cƌ˘1cƌ3g0_!̗/|˷0_3f̘1cƌ3fT/cƌ3fH0|˧0_˗0_>e̘1cƌ3f̘1#|3f̘1cƁ˗`|˗/c|-̗/|e̘1cƌ3f̘1cC8`A&TaC!Fx0_B$ 'P ,h@ O@8 ,h „ 2l!Ĉ'Rh"F2f̘1cƌ-O@$Xp |,h | H@O@ DPB >QD-^1_ƌ3f̘q`3f̘1cƌ3f̘1cF2f̘1cƌe̘1cƌ3f̘1cƌ32̗1cƌ3f/cƌ3f̘1cƌ3f̘a3f̘1|3f̘1cƌ3f̘1cƌ e̘1cƌ˘1cƌ3f̘1cƌ3fd/cƌ3f80_ƌ3f̘1cƌ3f̘1#|3f̘1cƁ2f̘1cƌ'p H?$X H*\ȰÇ1bĈ#Fa#F1bĈ#Fk/_ 1bĈ#F/_Ĉ#F1bĈE1bĈ#F1|5̗oa|":̗/_Ĉ#F1b#F1bĈ1bĈ#F1bĂA̗/a|#˗/bĈ#F1_Ĉ#F1bĈE1bĈ#F1b|˗/|ˇ0_>+`|#F1bD"F1bĈ#FD/bĈ#F1bĈ w0@'P`|˗o 8_8_| H*\ȰÇA"D!BQ`>!B"D!B/|(? O`|'p@_O`>'p "Lp!Æ:"D!B"D B"D!Bb>/_ G0߿|/_|3_˗_|A"D!"D!B"D B"D!Bb>/߿|+/|`/_|"D!B,"D!B"DA"D!Bb|3_>W`>'p` 7p`0@ 0 <0… .O@ ,? 4xaB 6tbDM8qĉ'N0|˗_|̗` '0_|/߿|`'Nh0Ć&N8qĉ'7qĉ'N8qb|3_|3/|O@ /߿| ̗O`|'p "Lp!Æ 9t80C:tСC*СC:tСCW0_> g0_9t0_>:ta| СC:tСC 9tСC:tСC̗`|ˇ0_>  ˗? 4xaB 6dϡC:tСC:tP`:tСC:tСÂP`| s`|:tСC:ϡC:tСC3ϡC:tСC:,a|˗Oa|:$/C:ta>sСC:t!C$8? 4xaB 6tbDK/_>k/_> G"E棘`> O@ DPB >0_|1bĈ#F1bD'p H |,h`A$XA .d|c/_>|Ç 3Ç>|Ç`>|Ç{0Ç>|Ç !w0Ç>|Ç6w0Ç>|Ç{0>|Ç&_>|Ç>t`>|Ç>a=|Ç>L|>|Ç>|x`> O@ DPB >QbB$X? W`8`A&TaC!1_Ĉ#F1bĈg0_Ĉ#F1bĈ 90_|#F1bĈE1bĈ#F1|1bĈ#F1|51_Ĉ#F1|Et0 <(? ,/_| H*\Ȱ!|30 <0‚ Hp`|,X |,h ‚ H`|3h0A4Ϡ8`A&TaC!1_ą  $0@ H |O@ DPB s(0|:t(0B 'P ,h   'p@$ A$H0A  <0… :|`"*̗/_ćc/_>1bĈ Ag0_ĈK/_>[/_˗a| ˗a>拘/bĈ#F`"&̗/bD)̗/a|#.O@'p ̇|!D!BC/C/_|"D`|ˇ_|!D/"!B"D!B"D|ˇ!!4!ƒ!̗|"D?O@(? 4x0w0_|7`> 7߿߿'p| G0_> <0!|G0| S0̧PB *TPB  ̧`> ˧`> w0_>SPa|)T/_| ̧aO`| 70|/|`g0_)LOB!̗`>̧a>)0@ /_>0 ? / /@8p|o  <0… :|`"'0_˗_|/_>_>G0|k/_Ĉ[`>ED/|70߿|o``|/߿|/_>#O`˗_ ̗_>/߿|_ 70_g0_>(0|E1bĈ#1_Ă3/| ̗/| /|+/_>"F/_|̗0_EPO'0_'P/߿@ /߿| o| o /_ 70_>80|O`'0/_80|8p|o  <0… :|`"'p@/_|0_߿'p (? 4x_|8|7? 8p8p˗/ 0@/߿/߿@ /|O o 8? /_|o|˗/_|8P`>˗ A G| $/,h „ 2l!D"s/_>70_'0_|'0߿| G0_>=w0_ 3_/_`| x0|_o`>/߿|#`| ;/|̗O`| '0|_>/|̗a>"̷0_|#F1bĈE`˗_|_|_ ߿/? o|? 4X0|70߿| W0_ w#`'0|'0_|`>g0|/_|0@O 0_'P`˗o|7po 8p@8`A&TaC!1| ̗/bă 0_>"̗` ߿|O| 8p8p <03` [pB̗`>-\(0| [p… .\pB̷_-\`|-/| ˗_ ̗/|'0_|˷0a [p…w0_|G0B  $/| g0_w`O@ DPB >h0_| 1̗/bD!̗oa| E-o|[`|-;/_-<`| ̗`-\(0… .a|˷0_| .\/_| w0_| ̷0B.\p… .B ? `| ̗/_> ,/_| ˗/|3hP`> 3/A ̗`> 3hР| 4hРA 3H0_|˗/A˗ϠA $/_| ˗/_gРA,Ϡ8`A&TaC!1|8`A 'p 80,/A/A ˗| gРA H*,'p@$X|,h „ H? "D!B ̇|ˇ|!̇| H*\ȰÇ#JH`"XbŊ!擘Oa+V<b>1_|拘bŊ+VXbE擘bŊ+VOb>*VX`>'p 'p  ,(0,h „ 2l!Ĉ'R4Oa>*VXbE&CbŊ;`K`+VXbŊCob+VXb> XbŅ3bE#bŊ+VXbE 棘bŊ+Vb|WbŊ 3`[/_|+VXbŊ+2̗/߿|*XbŊ!(`> 4xaB 6t? 4x!B$XA .dC%NXq!,hP`>$XA .dCE1bĈ3/bD1bĈ#F1bĈ1bĈ#F4/bĈ#F0|#*̗0_Ĉ#F1bĈ#F1_Ĉ#F1|#F1bĈ1O@ 'p A8`A&TaC!F8bE ]xŋ]xŋ'P $/_|  <0… :|1ĉ+Z\ŋ/^$ŋ/^̇0_|˗0ŋ/^xŋxŋ xŋ!̗b|xŋ/^x|/^x"|/^x|Ka|]xŋ/^xqa/^x`/^x_]$/|/^xŋ/^\ŋ/^$ŋ/^`| ̗_|O`>wŋ/^xE.^xE.^xEW0_/߿˗_| o| H*\ȰÇ#JHE.^xE.^xŁ w0߿|'`>'p`O@ DPB >QD-6wŋ/wŋ/̗/|O O@ O@ DPB >QD->wŋ/wŋ/w0_>_|3ŋ/^xŋ]xŋ]xŋ;O`/߿| xŋ/^x|/^x"|/^x|.̗ŋ/^xŋ]xŋ]xŋwq`|/^xŋ/^ŋ/^$ŋ/^D/E]xŋ/^xb'p "LpA$/,h „ 2l!ąE4/_Ĉ#F1bĈ#F1|#FD/bĈ[/bĈ#Fa|"̗/_Ĉ#F1bĈ#F1|#FD/bĈ[/bĈ#F!|'p  <0… :|1ĉ+Zņ.^/|/^xbC$X ,h „ 2l!Ĉ'Rh|1.g0߿| ̗/@ 7P࿁(0|80߿8_>O@ DPB >QD-^ĘQF1|O`>W0|!'0_>#o`>ѣG=zѣG91|O`+o`|!'0_>`ѣG=zѣG91|/߿|70_| ̇0|'0|70|=zѣG=zѣ|y_>_`> ߿| (0|'0|#/|'p "Lp!ÆB(q"Ŋ/b̨q#ǎ |/(0| (0|o` 0 <0… :|1ĉ+Z1ƍ;zL <0| O`|_a>'0|+`>$XA .dC%NXE5nc>g0߿| ̗/_> /߿?o`>˗/_> <0… :|1ĉ+Z1ƍ;zb>=zѣG=z|)Qa>=zѣG=zѣG y0G=zѣG=zѣGѣG=zѣG=z`> 4xaB 'p "Lp!ÆB(q"Ŋ/b̨q#ǎ? )r$ɒ&OLr%˖._Œ)s&͚6o̩s'Ϟ> *t(ѢF"Mt)ӦNB*u*ժVbͪu+׮^ +v,ٲfϢMv-۶n+w.ݺvͫw|˗/߬ H? 4xaB 6tbD)VxcF9vdH3/_>"E)RH"E)RHS/H"E/_|"E)RH"Ed/|D)RC$ <0… :|1ĉ+Z1ƍc/G9r0_|Ǒ#G9rȑ#G#0_>9ra| Ǒ#G9rȑ#G!sO`>9rQa|Ǒ#G9rȑ#G!s_>9rqa| ȑ#G9rȑ#ǂ H'p A H'p "Lp!ÆB"F1bĈ#F1bĈ#F0_Ĉg0|#1bĈ#F80_>1bĈ#F1bĈ#F1b|#w0|#1bĈ#Fd08 A$ <0… :|1ĉ+Z1|0_>iԨQ#|s/|4jԨQF5jԨa>c/Ƈ4jԨb3_4jԨQF5jԨa>S/FiԨQc| W0_>4jԨQF5jԨa>C/F4jԨb1̗a>5jԨQF5jdO|/_|'ӨQF0_4jԨQF5jԨqa>8P ,h „)TPB *TP!| ˧0_>'p "Lp!ÆB(q"Ŋ/b/cƌe̘1#|;/_2f̘1cƌ3f̘b3b̗1cƌA̗/_>1_ƌ3f̘1cƌ3^̗1cF2f̘c ? ? 4xaB 6tbD)Vx|3fĘ/cƌ11_ƌ3f̘1cƌ3^̗1cF2f̘ce̘1cƌ3f̘1|3fĘ/cƌ11_ƌ3f̘1cƌ3^̧`>'p 8`A 'p 80? 4xaB 6t`>"D H*\ȰC H*\ȰÇ C0@ O@˗` ˗/_'P࿁8p`>$XA .dC BT"D 'P ,h „ 2lP |'p "Lp!ÆB`|˗Oa|">̗/|̗/|#F1bĂ"FD/bĈ1bĈ#.̗/_Ĉ#F1|[/_|"F̗/a| 3/_Ĉ8`A&$8P ,/ H`A$/_'p@$XAK0a„ &L0a„%L0a„ &L0a„ 3/|C/_B&/|3/| &Lh0_„ &/a| ̗/_%O@$H0_| W`|/_| ,X`˗/_? o_߿/߿o`>̗/|7_˗O |7? 4xaB 6tag0_>A`|3`|A0D!̗a|!̗/DCa||/|'0| g0|70|_| 70_>`| /|;/D!B"|3`|3/_/|8@ ̗o|̗o| <` &L(0|˗/!|K`|KH0_K0aBO`|`g0|70_ '0߿|/|/_| 70߿|ˇ0_„ &L0a„ &L/|3`|˗`|/_> '0|˗_>/_>̗` &<`>70| O'p`8_8p|˗o80_8p|7p|8`A /| ̗O`|70|70߿| /߿|/߿|!`>70|70|"D!B"D!B!̗O`+/| '0_>_+`|'0_>"DH0|/| '0_|+`|̗!|C| CX0|C!o`>/|(߿߿@_/߿|o'p`o`˗/? ? H*\ȰC H| / (? 70|O`o@0  4`> ̗/| '0_|g0|4`>/? O (07p`|O@ O@߿|'_'p`80o`>'0߿|o| _(߿|@8P |O@ DPB w0_|G0߿|/_ ̗O`>_> #_> {h0ÅO`| G0|̗/|˗`> ̗0| '0|/_G0|3/|w0_| ̗O`'0| g0|70|_> 70_>o`| 70_|ˇ0_>=|Ç;a|̗o`>̗/߿|'`>_/߿ _'p`8p $| ̗_>O |70/_|7p`|8p`|(0_>o`̗_|/_|7p`|8p_|˗o`'0_|o`|(߿| /_>/|70@߿(߿o7P O@8`A&TaC&̗`>̗ϡC̗`>9L|C/_> /߿_'p|'p@@$X 'P߿|'p |,h?#(0_|$H|? 4xaB 6t_A"DA ̇0_> /| G0_ #/_ G0| '0@ /߿| //_80_>8p@80_>$XA .dС|{Ç{0_!̗C!̗oa|{H0| G0߿|/_ o`>70߿|o|8p@̗/|'P80_|8_ 8p 8p|8`A&TaC kÇ>t|˧0_ ˧0_=\|=|P`>3!|-̗!|W0Á˗Ç>|0_| =|Ç=T/_[/_˷0_|paC w0|̗a=$/| W0Á˗Ç>|0_|=|Ç=d08 AO@ O@$H`>'p ;xp` ˇ_|C_>'p "Lp!Æ 'p 'p "Lp!Æ 9tСC:T|9t`>3/_> `|*̗/|!p`>:tСCsСCСC:tPa>СÂ'p A$X`A O@(? 4X`> 'p| $? 4xaB 6tb|#F1b#F1b|O@ D /_| ,X?$XP ,h |CH0B8`A&TaC!61bĈ3/bĈ#FQ`1bĈ#F0_|E1bĈ#>w0_Ĉ#F`#F1bD;/bĈ#F1b| 1bĈ#F1|#Fx`> 4xaB 6tbD8`A&TaC!Fl0 <0… :|1D H*\` 6lذaÆ *g0_Æ 6lذaÆ *̧0_Æ 6lذaÆ &װaÆ װaÆ 6lذaCkذaÆ 6lذaCkذaÆ 6lذaÄ6lذaÆ 6lذaÆ 6l/_6lذaÆ 6l0,h „ 2l!Ĉ'Rh"ƌ7rO!|,h B H*\ȰÅ>|Ç>|Ç>|Ç>|`>{a|>|Ç =|Ç>|Ç>|Ç>|!||=|Ç{Ç>|Ç>|Ç>|C!|>|Ç=|Ç>|Ç>|Ç>|!|s|>|Ç=|Ç>|Ç>|Ç>|!|{|>|Ç? 4xaB 6tbD)VxcF9RG0_>O |70߿|7߿ @$XA .da|>|Ç>|Ç>|Ç>|x0| /߿|/_|/| /_|#/Ç>|p`|>|Ç>|Ç>|Ç>|0_| G0|70߿|'0߿|W0Ç>|0_|>|Ç>|Ç>|Ç>|0|O`|_> /߿O@$XA .dС@$XA .dC%NXE5n_| /| ̗/߿|/_>/_|QD-^ĘQF=~0_>W0_!C 2dȐ!C 2dȇ]0_|B 2dȐ!C 2dȐ!#2a|!C 2dȐ!C 2dȐ`|B 2dȐ!C 2dȐ!'˗/d| 2dȐ!C 2dȐ!CZO@ DH? 4xaB 6tbD)VxcF9vdH8`A&TaC!F8bE1fԸcGXA9dI'QTeK/aƔ9fM7qԹgO?:hQG&UiSOF:jUWfպkW_;lYgѦU1 ;;PKyVtVPKFJOEBPS/img/select_a.gifxGIF87aP?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,P H*\ȰÇ!'p " <0… :|1ĉ+Z1ƍ;z2#|'p O@$XA .dC%NXE5nG`|B 2dȐ!C 2dȐ!%˗/$| 2dȐ!C 2dȐ!CF̗`B˗/dȐ!C 2dȐ!C b|R`|!C 2dȐ!C 2dȐ̗/߿|3/_|`>8`A&TaC!F8bE1fԸcGA:̗`|˗_|_|˗_>`|!C 2dȐ!C 2dȐ +O`+O`'0|˗`|!C 2dȐ!C 2dȐ W0| W0|˗_>'p 'p ", <0… :|1ĉ+Z1ƍ;z80_̗_˗`>_>'0|@̗$H A $H A 1| ˗_|'0?/߿ O|8`A̗? 4xaB 6tbD)VxcF9v1_|!qa?~Ǐ?~"|,h | $0@ Hco!|,h  H <0… :|1ĉ+Z1ƍ;B'0|Co`>_|$0 'p "Lp!Æ8@$XA .dC%NXE5n1_|;/_|!W0|;vda|:vرcǎ;vرcNj`| ̇0|uؑa:vرcǎ;vرcNJ3`>ccǎ Aױcǎ;vرcǎ;N̷0| )O| H?$XA 'p  ,(0,h „ 2l!Ĉ'Rh"ƌ7roaC0@ ˗/_ ,X`A $H| H*\ȰÇ#JHŋ3jQb.c`|˗Oa|:j̗/|uرcǎ;vرcǎ-w1|S/_|:v̗`:vرcǎ;vرcG滘a>-̗a|u`>g0_|;vرcǎ;vر| 8`A8|+Xp`|W0_,X |,/_ ,(0,h „ 2l!Ĉ'Rh"ƌ7r#|3`|+/_|'0_'0|/|˗/_˗`|Iױcǎ;vرcǎ;Jױb5̗o`> /߿|˗O` _|/߿|/߿|˗_> ̗Ob;vرcǎ;vQba>3O`˗o`70_| ̗_˗_|/|;vرcGuQGuԑDO@ Da| 'p@'0߿|˗/߿|'`>o`'@ /_8p| H*\ȰÇ#JHŋ3jQbk/|'0߿|˗O` '0|O`˗/߿|̗b;vرcǎ;vQb3`| ̗`>˗O`|3/@ /߿@̗o(0,h „ 2l!Ĉ'Rh"ƌ7rc|g0_ Øcǎ;vرcǎ;v|;/_E O@ QDha>,Zl/_>[/_>˗"| Y(0BO@ ,0@ H*\ȰÇ#JH|-:0E8p $0@ H O@$X| ;x ;(0_|!'P ,H`> 4xaƒ H!$!Ḃ0_>"DH0_>$XA .dC%NX`'0|˗o`|˗o`|Ka>-Zh"| !̗/|`| ̗/? O̗ A$H|$/,h „ 2l!Ĉ'RH0| '0_|3O`| /_| YhѢE[`>G0| ̗O` ˗a C`|-ZhѢE-:w0|#`>G0_| -gѢE-Ztoa`>#O` g0_>O`|/_> ̗O`|hѢE-Zhqa>3/|-̗o`%G0_|-ZhѢE`|G`$/|#/|/߿|/߿|/߿| G_|'p "Lp!ÆB(q"ň;/_|/_|1̗/߿|K`*VXbŊ ;_>/_|̗/_K` '0_/߿|g0_g0_|+VXbŊ+O@8_>`>/$`> 4xaB 6tbD 'p #`> A8p?/'0_| 08`A&TaC!F8"|+O`>'0_ ̗/|K`+VXbE3/|G0|'0_|g0|_>/߿|O`> +bŊ+VXbE;/_|O`| ̗/_'`>  <0… :|1Ć;/_|˗_|˗/_>70_| ̗`|˗_>/_ '0_|G0ĉ'N8qĉ'7q&N8qĉ'NoD 7q|&N8qĉ'N8`'7qĉ'N8q|'"g0_ (? ̗? 4xaB 6tbD)VϢE,ZhѢE!hQ`Y(0_>-ZhѢEha>-ZhѢE,Za|-gѢE-Zh"|-:gѢE-Z1E!̗/EhѢE-Zhb>hѢE-ZϢE˗/EgѢE-ZhѢD$XA O@ DPB >QD HO@8`AO@ DPB >QD-^ĘQF=~RH%MDRJ-]SL5męSN=}TPEETRM>UTU^ŚUV]~VXe͞EVZmݾW\uśW^}X`… Fl`>'p "Lp!ÆB(q"Ŋ/b̨q#ǎ? y1_|˗/H"E)RH"E)Rȁ̗/H"E)RH"E)R)̗OH"E)RH"E)2d| 'RH"E)RH"E 2_>)RH"E)RH"E0_>"E)RH"E)Rȏ9/H"E)RH"E)R|)RH"E)RH H*\ȰÇ#6O@8`A&TaC!Fd <0… :|1ĉ+>gѢE-ZT/|YhѢEgѢE-ZhѢ,ZhѢE g0|-ZhѢń,ZhѢE-ZϢE-Z0|hѢE-2̗ϢE-ZhѢE,ZhѢE c/E-Zha>-ZhѢE)hѢE-6̗oa|-ZhѢE,ZhѢE-ZϢE-Z0_hѢE-:gѢE-Zh"|-ZhѢŇ3/_>-ZhE? 4xaB 6tbD)VLϢE-Z`>'p "Lp!ÆB(1D%J(QD%J4OD%J(Q|(QD%J0D%J(QD%J4OD%J(QD%J(QDI(QD%J(QD$J(QD%J(QD%J0D%J(QD%J4OD%J(QD%J(QDI(QD%J(QD$J(QD%J(QD%J0D%J(QD%J4OD%J(QD%J(QDI(QD%J(QD8`A&TaC!F8bE1f̘OF5jԨQ|5jԨ |,h „ 'p "Lp!ÆB/bĈ#F1bĈ#F/bĈ#F1_Ĉ1bĈ#F/bĈ#F1bĈ#F/bĈ#F1_Ĉ1bĈ#F/bĈ#F1bĈ#F/bĈ#F1_1bĈ#F/bĈ#F1bĈ#F/bĈ#F1| /_|/_ O o`>? 4xaB 6t"|#F1bĈ#F1|#F1bĈ/| 70߿|/| /|1bĈ#F/bĈ#F1bĈ#F/bĈ#F0|˗O`/|#o`>`#F1bD"F1bĈ#F1bD"F1bĈw0߿|/|3/_| W0_>1bĈ#F1_Ĉ#F1bĈ#F(0_Ĉ#FQ!| O_/A70|'P  O| H*\ȰÇ1bĈ#F1bĈ1bĈ#̗/_/|O`|˗/_+/|3/_#F1bă"F1bĈ#F1bD"F1bĈ!/| ̗_> ̗/|o`>O`|%1bĈ#Fh0_Ĉ#F1bĈ#F(0_Ĉ#F`>;_>˗/_˗/߿| G0_|`>"F1bĈ 1bĈEQDEQD P>$XA .dC"| A"D!2"D!B"D!B"D!B\a>!2̷0D!B"|!B"D!B"|!B"ą"| A"D!2"D!B"D!B"D!B\a>!2̷0D O@ DP‚ H'p "Lp!ÆB(q"Ŋ YhѢņhb˗/|k/_|-ZO@$XР| H*\ȰÇ#JHb|-Zha> H*<+X`|˗`O@ DP‚cP`> 2dȐ!C 2dȐ!C 2ǐ!C 2dȐ| 2dȐ!˗Oa| cȐ!C ǐ| 2dȐ!C 2dȐ!C 2d!C 2dȐ!Á2dȐ!C1̗oa|G0_|1d_>K/_> 1dȐ!C 2dȐ!C 2dȐa> 2dȐ!C cȐ!C  ̷0_>̗| ca>ǐa> 2dȐ!C 2dȐ!C 2ǐ!C 2d!(,h „ 2Loa g0_˗/|'0_>/߿|/_|˗/߿|/_/|pa 6lذaÆ 6lذaÆ kذaÆ 6\` 6lpak/|+_|˗_/_| ̗/߿|3O`|/߿|_|/_ Pa 6lذaÆ 6lذaÆ kذaÆ 6dO`| 6lذa| ? W0_|'0߿|/_|70_O`| 70_/_̗`O@ DPB >QDhѢŊ H*\ȰÄ H | O| /|70_|70_/_|_|70_ @ H?  <0… :|1ĉ+&gѢE;ϢE˗a>W0߿|˗_/_>˗_|/| /|/_3/|hѢE-Zhb>-Z`>-Z|O` O`|'0|'`>o| (0_ _߿ /8p| H*\ȰÇ#JHb|-Z(1E-Z,a|hb| [ϢE-ZhѢE,Zh1b>-Zh0_>̗C O@ l/_c0 

8`A&Ta:,a3/_СCsϡC:t |O@(? 4xaB(? `| 3hРA380_| 4h|'p "Lp!C64ϠA Ϡ|4hРA <0… ;O` @ A ̗ $/| $H A G0A#H| H*\ȰÇ#JH| 1w0_|˗/| 70_>˷0| 0_>-Zw0|o`c`| ;/_|Y`>1gѢE-Zh"| 1w0|o`>g0| 3`>+/E-;O`| '0| c`|w0_/_|/_|˗/߿|/_/|̷0_>-ZhѢEK/C8_>G0_ ̗|#/_>/_|˗/A/߿| ̗? 4xaB /|/|g0| ̗a| g0_/_>+O`|/߿|_|/_ #` 6lذaÆ 6lذaÆ COa>#O`| /߿|G0|˗_O80߿| /  <0… w0|'0|G0_|5/|'0_#`| ̗_>/|/_70_ 6lذaÆ 6lذaÆ +/|̗/_/_|_> ˗`70_|W0߿|`|5lذa Hp '0||'p 8`A70߿| 7p`|˗_>˗/߿|0@ 0 <0… :|1ĉ+Z'0_|/_|080߿|o |O| ̗/߿|O| H*\P`| '0_>`k(0|'0_|'0|O`O`˗/߿|̗` 6lذaÆ 6lذaÆ 6_/߿| /_ +/_>_|˗O`>O` W0_Æ 6l/߿| '0_>˗/|5̗`> '0|˗/| g0_ _߿ /| H*\ȰÇ#JHń;`˗/| g0|3|@/|7p`|O@ DPB5lx0_Â5̗` 6\aÆ 6lذaÆ 6lذaÆ kpa6lh0_ 6l0a kX0_!|'p ̗? 4xaB 6tbD)V1Ew`>8`|8`A&T| `| C/_Æ ̗aÆ 6lذaÆ 6lذaÆ kpakذ|6lذaC6<|˗0_| 6lh0_ 6lذaÆ 6lذaÆ 6\aÅװaC5lذaÆ 5lx0_Ã;/_>kذaÁkذaÆ 6lذaÆ 6lذaC6\/a|6\/_ 6lؐa k0_|˗/_C O@ D |'p "Lp!ÆB(q"Ŋ)0B O@ 0@ H*\Ȱ!|,hA$XР@ O@ DP!,h „ 2l!Ĉ'Rh"|,h  HP |,h | H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿  3a„C'p "Lp!ÆB(q"Ŋ/b <0… :|1ĉ+Z/_/^xb/^xb|.^xŋ/^0_/^x|/^x|.^xŋ/^0ŋ/^x`/^xb/^xŋ/"wŋ/^xŋ/wŋ/^xŃ.^xŋ/^xń.^xŋ/^h0ŋ/^xŋ/^0ŋ/^xŋ `> 4xaB 'p  H'p "Lp!ÆB(`'N8qĉ'N0Ĉ&N0_B O@ $0@ H*\ȰÇ#Joĉ'N8qĉ'271b'.̇0_|'˗oĉ'N8q|'N8qĉ'N8aM8qa8q`|'N8qĉ8qĉ'N8qĉ Ma|'P70߿(0|`>_>|$H| G A'p "Lp!ÆB(_'N8qĉ'N0Ĉ/|O`|̗_|70|g0_ 1_'N8qĉ&N8qĉ'N8q"|#;o`>70|̗_|70|g0|˗_| ̗/߿|'0_|˗`'N8qĉ&N8qĉ'N8q"|`| ̗/_>'0|(__O|˗_|/__˗/_  <0… :|1|%J(QD%J(Q|!a|_|˗o`>/_0@ /|o` /|/߿||8`A&TaC!FOD%J(QD%J ̗/߿|o` O@ o` /|/߿|o@$ <0… :|1b|%J(QD%J(Q|;_> '0|O`|!̗O`| 70|̗/|˗_|/߿|/߿|˗O`>!̗OD%J(b>%J(QD%J(`>'0|O`>O`> ̗O``;/_O`>_˗_> [OD%J(a>%J(QD%J(`>-? 4xaB 3/C [/C 2dȐ!C 2!C 2dȐ!C 2dȐ!C ǐa2dȐ!|cȐ!|cȐ!C 2dȐ!C1dȐ!C 2dȐ!C 2dȐ!Ã.0C 2D`| 24/2dȐ!C 2dȐ| 2dȐ!C 2dȐ!C 2d`> 1ǐ!C C/C ˗| 8`A&T 0 wa|cŋ-O@$XA  ? 4xaB 6tbD)Vh0| ]h1B O@ 0@ H| 3hРA 4h`|˗ϠA /_>  <0… :|1ĉ+Z4b> H*\H? O@ < g`> 4hРA gP`| 4hРA4hP`>$XA .dC%NXѢ|]xŋ 1̇0_|70| /_|˗|'p? @7p|8p@/ ̗o? 4xaB 6tbD)Vh0|/^x| '0_/|_'0_|'0|嫘`Iwŋ/^xE,wŋ/.̷0|#/߿|/|G0| ̗/߿|;`|/_|˗_'`>'p`|8p`>$XA .dC%NXѢ|]xŋ '0|/߿|/߿|w0_|˗/|˗`|˗_|˗/߿| /߿|˗_$xŋ/^x|xŋw0߿|W0߿|/߿|˗/_K/_|%W0_|70_> /|70|Iwŋ/^xE 'p "Lp!ÆB? /@/߿|o|oo 8? o`|_>o`>/_/,h „ 2l!Ĉ'Rh`>]xŋ `|o`>/|#/|Ko`+/_/_/__˗O`0ŋ/^xŋ kŋ/^x0|˗O`| '0_/_|˗/| ˗O`/| ̗/߿|˗/߿|'0_|;`.^xŋ/^h0|/^xŅ.^(`>? 4xa| K80,h „ 2l!Ĉ'Rh`>.^xŋ ]xQ`]/_| ]xŋ/^x`.^xŋ ]xQ`]/| ]xŋ/^x`.^xŋ ]xQ`>]/_xŋ/^x| ]xŋx| wa|[ŋ/^xŋ-wŋ/^dŋ)O@$XAˇP`>'p "Lp!ÆB(q"Ŋ [ŋ/^`> 4xaB 'p A H'p  ? 4xaB 6tbD)Vh0|/^xŋ/^xa.^xŋ/^h0|/^xŋ/^xa.^xŋ/^h0|/^xŋ/^xa.^xŋ/^h0|/^xŋ/^xa.^xŋ/^h0|/^xŋ/^xa.^xŋ/^h0|/^xŋ/^xa.^xŋ/^h0|/^x"E$XA .$'p " 'p "Lp!ÆB(q"Ŋ [ŋ/^E˗|]oa/^xŋ/̷0ŋ/^H1ŋ!̗|]oa/^xŋ/̷0ŋ/^H1|O o` O| /? ߿808po|(0_>$X | O@ DPB >D0 <0@$`> 4x@$XA <0… :|1b| ̗O` '0_/_>o` ;/ā拘/D(QD% 'Qb| 'Qb|$>̷0D%J(Q| '0_|o`˗O`o`>3/|˗/__| O| /8p`  <0… :|0D !̗/D1|!B"D`|̗/_70|(__O|/@/_/_|'0߿|/_o80O@ DPB >D"Ć| >̷0D!B"Ć!̗/|˗_|̇0߿|/|(? /_ o`|_>o`>o80O@ DPB >D`o`>'0_|˗/|X0߿|=̗| A"D!B408|̗/_70_/| 70_ 8? o`|_>o`>08`|  <0… :|0|'0߿| W0|S`| #b|["D!B"|g0_/| ̗o`> ̗O``+/߿|/_>_>/߿|;/a>"D!6'0|'0߿| W0|)70|/_'0_|˗/|˗/_> :̷0D!B"ā`| 70|O`> ̗O`| O|(P`>˗O@/_/_O`| 'P (P`>$80_'p "Lp!Æ/|(_//߿|o| /߿|˗/_/߿|/߿|o|8`AC80,h „ 2l!D)1bĈqa| 1̷0_Ĉ#Fq |O/_ | | `>'p`'0߿|'0_'0 (? 4(0A8`A&TaC!*̷0_Ĉ#;/_Ĉ [a"F1bĈ+/|˗O`+O`|)W0_>/| /|/|3/_-1bĈ#F0|#Fa|#"̗a1bĈ!;_ ̗O`+O`|)G0߿|/__|'0_˗/|K/| O@ DPƒ Hp |,hA$X`>4hРA 4hP`>gРA ̗ϠA g`>$XA .d!| w0_> 70|o`w0|̗/߿|'0|'0_>O`>{80|=|| (? 4xP |'p ,ϠA 4hРA/_> 4h_| `| O@ DPB .̷0Ç̗C1P` {Å˗Ã0|>|0B O@ 0@ H| 3X0,h „ 2lpa>|`|6̗a-g0Ç.̇0_|*̗a H*\H? O@ < g`>'p "Lp!Æ[Ç!|{(0|!̗/| 70߿|˗/_0@ /_| ̗o| ̗o/8P`|/,h „ 2l!D[/bĈ#FtoaC/_ 0_| w0|O`|˗O` /| ̗_> ;/_Ă拘/|#F1bĈ -̷0_Ĉ#F0|#.̗0_|# ̗/|-g0|#/߿|/|G0| ̗_w0|˗_| ̗/_'0_|˗`| E1bĈ#6̗Oa"F1bD'p "L(? O@ D8? Ϡ g0|/߿|/߿|gP`> '0_|#O`/_/߿|'0߿|/_|G0_| H*\ȰÇSoa#Fa#F_E̷0|W0߿|/߿|˗/_C/_|!W0_|70_>/|70_> G0|"F1bĈ!ˇ0|#F1b|#F1bD"[080 _>'0_7_o`>0(0'0߿|_'0 H*\ȰÇ#J$O@ DPB *Ç>|h0C3`|o`>/|#/|Co`>+/_/__|_˗/|#Ç>|Ç)Ç>\Ç>|`)g0|/_| ̗_>˗/_>G0|a>3/_>O`>'0߿|/|Ç>|Á{Ç(O@ DPB >D`3"D;"D B"D!Bl/a B"ā"D!B(0_>w0|!Bx0| Bd/D!B"D ̗a>!Bx`> 4xaB 6tbD80,h „ ̇0_> ̗!C 2dȐ!C 240 $ <0… СC:t| 3ϡCˇ0_>˗ϡC:tСC s0C:t0C:tСC9,`>:t/_|9t0_|:tСC:tx0Ã:tСC:tСC:L`>:t/B O@ $0@ H*\ȰÇ#J,oĉ'N8qĉ'N |,h „ O@8`A O@ DPB >Q|'N8qĉ'N8qb|'N8qĉ'N8qĉM8qĉ'N8qĉM8qĉ'N8qĉ'7qĉ'N8qĉ'F7qĉ'N8qĉ'N80ĉ'N8qĉ'N1ĉ'N8qĉ'N8q|'N8qĉ'N8qb|'N8qĉ'N8qĉM8qĉ'N8qĉM8qĉ'N8qĉ'7qĉ'N8qĉ'F7qĉ%'p`>$XA .dC%B7qĉ'N8qĉ'F7qĉ#˗/|8qĉ'N0ĉ'N8qĉ'N1ĉ'N/|M8qĉ'Nloĉ'N8qĉ'Noĉ'>̗Oa|'N8qĉ8qĉ'N8qĉ#8qĉc/ĉ'N8qą&N8qĉ'N8qĈ&N8q|7qĉ'N8qa'N8qĉ'N81b'N0_|&N8qĉ'.7qĉ&h&h&("'p "Lp!Æ s_>|Ç>Ç>|Ç>|a|>|CÇ>|Ç=|Ç>|Ç>|0Ç>|`> O@8`>$X HO@8`A'p "<? 4xaB 6tbD)Vx`>1b/_|a|h1BO@ 0 H O@ DPB >QD-^<#F1w0|!̇`>%̗/Ɔ0F1bĈ#F'È|;`| a4|1_|È#F1bĈ|1ba| kc| 70_>'0|ˇ0|*o`al#F1bĈ#FaĈbS/| ;o` '0߿|_>w0_惘/Ɔ0bĈ#F1b81F/ W`| $` WP`70| ̗O`| W_|'0_|˗O`|/_>/_|W` ? 4xaB 6tbD)Vx`>1^0_|0Ɓ;o`>'0| /߿|O`|/_/߿|O`|/_|̗#|1bĈ#F1b#FAO@ H| 4H0_>(߿|70߿|'p|˗| ̗O`O`| ̗O`>#H A $? 4xaB 6tbD)Vx`>1^71_|&08_˗/|O`|#8`>'p`'0߿|'0_'08p ,h`>$XA .dC%NXŃ0bx1F(g0_/|O`>70|3/߿|˗/|_>˗_|3/|0 ̇#F1bĈ#Ɖ0bx1F&;_`> '0|'P G0߿| ̗/߿|'0|'0_>O`>#HP`> $H_>$XA .dC%NXŃ0bx1F$S|X1_>0ˇ#F1bĈ#Ɖ0bx1F"[|H1_>0È#F1bĈ|1b|-̇ba/|aĈ#F1bĈqb>1^0Ɓ"[|1_0È#F1bĈ|8`A& HA HP`8`A8`>  8`A&/a| *D/_>)TH0,h „ 2l!Ĉ'Rh|a`K/_>K/b0Z̧0_|0&̗/_0È#F1bĈ|a`C/_|!1B$XA 'p A H'p 4h`>$XA .dC%NXŃ H1|1w0_>1F1b4b>1bĈ#F1Ng0| ̗/_>o`C`/| c`|˗`0bĈ|aĈ#F1bĈb/߿|o`>O` ;O`| g0|(0_"È#FẎ#F1bĈ#Ɗ 3`#/߿|'0| w0|/8p 7p`|_|/@ 7p| <0… :|0Ă B"D!B"D!:̗o`> /߿|70߿|G0߿| '0_|̗0| /|/_| #oa B"D(0_>!B"D!B"D˗/|/_|+_˗/A˗o`>8`A /߿|'0|0 <0… :|1D H*\ȰÇ#JHŋG0߿|`Oa70|0_ O'?G A8`A&TaC!F8bE1fԸcdž 70߿|o`>Oa>;o`>#a| '0_> ̗`> GP`|_|Gp`>  <0… :|1ĉ+Z1ƍ;>a>.曘/| ѣG=zѣG=Ba>.曘/| ѣG=zѣG=zϣ|]G1_>yѣG=zѣG#0|U̗b|/| 2dȐ!C 2dȐ!CZw0|_/_> 2dȐ!C 2dȐ!C`_+_3/dȐ!C 2dȐ!C EO_|/A8`A&TaC!F8bE1fԸcGAN̗/_O`|W0߿|30 $ <0… :|1+Z1ƍ;z1| /|o`>g0| A $H A $Ḣ0_| ̗_>70| ˘$H A $H A `@"̧1H A $H A d|DOc> A $H A $H 0| A $H A $Ha@ $H A $H 3$| $H A $H Ag0H6O@ DPB >QD-^ĘQF=~ |,h B HA8`A&TaC!F8bE1fԸcG' ra> A $H A $ȁ@\$H A $H A r`>  $H A $H A$ȅ@ $H A $H  ra> A $H A $ȁ@\$H A $H A r`> H*<'p "Lp!ÆB(q"Ŋ/b̨q#ǎ?Ng0H $H A $H A`>$H A $H A90| 9;$H A $H A r`>_/_;/|%w0H A $H A |70߿|O`'0|/a@ $H A $H 3`'0߿|̗_|̗o`;$H A $H AH? /|/߿| _80_|o? 4xaB 6tbD)VxcF9vq"| O_|/A'0| O H*\ȰÇ#JHŋ3jȱǏw0| ̗_ O`|˗O`;$H A $H A r`>_>'0| ̗`| 70_| $H A $H Ag0| '0_˗/|+` (? /,h „ 2l!Ĉ'Rh"ƌ7r|` HO@8`AO@ DPB >QD-^ĘQƌ ȑ`(1B O@ <0@ H*\ȰÇ#JHŋ3jx1|9w0|%K/_> Ǒ#G9rȑ#G9"g0G̷0G1b|9rȑ#G9rȑ|qH0| !̗/|`| ̗/? O|˗? 4xa|O@ DPB >QD-^ĘQF 'p "L G|/߿|#| | <`'p "Lp!ÆB(q"Ŋ/b̨q#|9N̷0|W0|'0|̗o`|'p A#@ <0… :|1ĉ+Z1ƍ Ǒ| w0_> #`#_|_|˗_>O`|/߿|`|9rȑ#G9rQc>8rOa|'0_|#/_|̇0_|G0|/| ̗_>`|9rȑ#G9rq"|, <0… 8@$/߿|G0|0(0'0|0@_'p | <0… :|1ĉ+Z1F3oƊg0_+`> ̗O`> ˗`|˗_|/|_>/|˷qƍ7nܸqƍ);`+K_'0_|˗/߿|/_|!G0߿| ˗O`|O`| O|o 7p8`A&TaC!F8A$XA .d? 4xaB-, |,h „ 'p`  <0|)TPa| ˧PB *TPB *TPB SPB *DOB *O|)TPB̧_> *4`| *Tx0_>)TPB *TPB *TP‚*TPB SPB Sx0| *TP|)OB C/B ̗O| *TPB *TPB *T`> *TPB*TPBg0B *T/| SPB˗OB /? 4xaB 6tbD)g0| O?˗/|/|/_o`? 4xaB-4`0 ||o@7p`  <0| ˧PB˧`> *TPB *TPB *TX0|'0| 70|`| '0|_>;OB *O|/_>#`>'0_ /|̧_> *4O? O@ ,0@ H| H*\ȰÇ#JH`>˗O`>o``| ̗`|_>w0_ŊEg0|O`> _#`>3o!|,h „8@$XA8`8`A&TaC!F8b|O߿?/߿|˗/|#/߿|/|$? 4xaB-4`_>+O`|#`3o… .\p…-\p… .\p… .\`/_>0@ /_|˗/|o`|_#/A'p "L`w0߿|'0|/_|'0_|;a>.\p… .\0… .\p… .\p… w0_|O`;O`|̗/_>W0߿|` HA H K`>'p| ̗O`>'0_>G0|$08`A&TaC"D!B"D`|O`;O`|̗O`>/| ̗_h0_> /|'0_>+O`| /|'0|A"D!"D!B"D`|O`;o`/|˗O`| '0_'0_|`>w0߿|`| 70߿|/_|˗o`>'p`>$XA .dÄ B"D!B|A"D &"|3"D "D!B/D!B"D!B`>!B0D B|Aa> B"D"D!B"D"D惨0DA`>!6g0D!B|!B"D!B_ B"|q`>"Ć "D!B"D!B"D!W0D!BDB'p ̇|!D!B 3!B"D!B"D_>$XA .dC%N`>)RD|拘`>)g0E)R0E)RH"E O@ DPB 8`A 4xaB80,h „ 2la|!B"D!B_>!Bb|!_>!B\"D!B_>!B"D!BL`>!Bb|!_>!B\"D!B_>!B"D!B,0'p "Lp!ÆO@8`A<80!Bb|A|!B0D!B|!B"D!B|/|8`A&TaC(0o 7p8`> 4xA$XР| H*\ȰÇ A"D!Ba>"D!6W0 _> BD|!B"DA"D!Ba>"D!6W0 _> BD|!B"DA"D!Ba>"D!6W0 _> BD|!B"DA"D!Ba>g0| O?˗O`˗/| '0A/_> /߿߿8_>$H| $/A GP`> ̗_o`>#80A $80,h „ 2la|!B"D!B||̗_| '0|'0_`>'0| '0| 70߿|;`>A|70_'0|'0_> *"D!B(0D!B"D(0|/| 70|/|G0߿|G0_o`˗/|Q`>A` ̗_ '0| g`>$X`| H*\ȰÇ A"D!Ba> w0? /߿߿80o|˗o /| /@/ 7p7p8p//__>/'p  O@ DPB >\"D!B"DA$/߿|/_| 7`>80 o`80_|7P`70| /߿| /߿|8p@8p|8p|8_|/߿|'0|7p|8p@'p "Lp!Æ2"D!B"ć ̗`|70| g0| /|/|g0|̗O`|h0 ̗/|_'0|O@ O@ DPB >t"D!B"DA<`|O`3/|_> ̗_>O`>o`w0ă a/߿| ̗O``>!B"D A"D!Ba>̗O`| 70|˗O`˗/|O`|˗o`>/_| ̗`>A"|'0߿| ̗o`|˗/|!B"D <0… :|1ĉQ"E)&Gq`(Gb>)RHb|)RH"E80E)RL|Q$"|)RH"ň(RH"E).Gq`>)R0Ł"H0E(RH"EQH"E)R\|)RH1a>EG`>QH"E#H"E)R0Ł(RHb|拘"|)H"E)FG"E)RHqa>QH"ń(1E(RG"E)RP>$XA .dC%N@$XA .dСA$XР|w H 'p "Lp!ÆBH0D%J(QD I(QD%61D%J(QD%'QD%J(Q|%J(QDA'QD%J(QDI(QD%J0D%J(Q|(QD%J(QD$J(QD%J`>%J(QĈ3OD%J(QD;OD%J(Q"|(QD%J`I(QD%J(Q"|I(QD%JO@ DPB >QD-^ĘQF8`A&TaC!F/ĉ'N8qD&N8qĉ'N8a'N8qĉM8qĉ'N$oĉ'N8qĉO@ DPB >QD-^ĘQF=~RH%MDRJ-]SL5męSN=}TPEETRM>UTU^ŚUV]~VXe͞EVZmݾW\uśW^}X`… FXbƍ?Ydʕ-_ƜYfΝ=Zhҥ;;PKxxPKFJOEBPS/img/lobtrim.gifGIF87aPP?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,PP H*\ȰÇ'p "O@ DPB >QD-^ĘQF=~`>8`A'P ,h „ 2l!Ĉ'Rh"ƌ7r#Ȋ i0_|!C 2dȐ!C 2dȐa|B 2dȐ!C 2dȐ!!ˇ0_ 2dȐ!C 2dȐ!C/|B ̗/dȐ!C 2dȐ!C a|8P  ̗/| OO ,h „ 2l!Ĉ'Rh"ƌ7r#H̗_|˗`|/__| 2dȐ!C 2dȐ!C 0_70| ̗_>/| 2dȐ!C 2dȐ!Cd/|`>˗/߿|`>0 < ,h „ 2l!Ĉ'Rh"ƌ7r|˗`|'0|_>/|y0_> A $H A |308P`> /߿oO@ Dh0,h „ 2l!Ĉ'Rh"ƌ7rc>}#|?~Ǐ?~cE$X A$(0_,H`>8`A;xO@ DPB >QD-^ĘQF'滘a>yt/LJco!|,h  H <0… :|1ĉ+Z1ƍ;B'0| ̇0|y1a>=zѣG=zѣ|̗_#`>=&ѣG=zѣG=z/|a c|=zѣG=zcF$(߿| (`> O@ DPB 'p 8`A&TaC!F8bE1fԸ|g0_C`:v0|;vرcǎ;vرc| g0|!70|;vdb;vرcǎ;vqb.cO!|O@'p "L? W`'p "Lp!ÆB(q"Ŋ/b̨q#G滘a>'0_|'P ,h „(?#H 8`A&TaC!F8bE1fԸ| ]0|̗/|uԘ/_>"رcǎ;vرcǎ#cb> ˧0_1_|Eױcǎ;vرcǎ;F0| ̗oa|+c|g0_"رcǎ;vرcǎ#c0 $+/_/_ ` W0_A`'p "Lp!ÆB(q"Ŋ/b̨q#Lj:VG0_> ;`|˗O |'P`˗O`|˗/߿|_|7P`80,h „ 2l!Ĉ'Rh"ƌ7rc|k/|̗_|˗O`| /|/߿|˗/_˗/|71_ǎ;vرcǎ;v1_G 0|'0_`/|70߿| 70_Qױcǎ;vرcǎ;Fc|'p@O`|O@_>/|(߿ ߿ H8`A&TaC!F8bE1fԸc|5s/|'0_|70_ 70߿|/_>˗O`]ױcǎ;vرcǎ;FQc|̗o`>_|˗_| O8p`߿8`A'p "Lp!ÆB(q"Ŋ/b̨q#Lj:j̗a:v,c;vرcǎ;v1bc/|,'p ,h`|"D? 4xaB 6tbD)VxcF9Fqc| C/_ǎ˘cǎ;vرcǎ 'p "L ` ,X`,/_A+X` ,X|,X`| O@  H8@ O@ 'p | Hp |,h /_| $0 < <0… :lÇ -C3/_{|=\a| 8p $0@ `>8`> $H_>'p@$H`>8`A(? 4xaB 6t0Ç[Ç8p $0@ H O@$X| ;x ;x ̗/|$/_wP`w_| ˗ |!D`>"D_>!/B!D/_>"D/|˗/C!|!D!B"D!BO@ O/_ 8`A&TaC!Fta ˗o`|g0A7P|߿| o 8P`| ̗o/ 0 O@ ̗ $/A  A'p "Lp!Æ;`>+o`/|%̷0Ç>|Çc`>O`|̇0|'0_>w0_>˗a| C`3/|`=|Ç;`#`W0߿| -Ç>|C-w0|'0_ C`/| 3/|3/|˗_| g0|g0|̗`||߿|?(0,h „ 2l`>3/|)̗/|˗0|=|Ç>|`>;o``C`/| #_| O`| O(08P` 7p`8p@/˗/|/__| /| H*\Ȱ|Oo@$`>(0߿|7_'p "Lp!ÆB(1_;o`'P /߿| 7|O|˗o7_̗o`/ (0|808p@/_ ̗/@_߿8`A&TaÁ Hp GP`#`>G_0 <0… :|1ĉ8_/|'p@`_|08`A(_>08P`GP | O@8P '`> '߿/߿ (? 4xaB 6d_ O`#/| ̗/߿| СC:tСC`>/|̗a>O`W0_|W0_>/_̗`|70_>a3O`|/߿|˗O`#/|:tСÂ;0|'p`| O'p`'p "Lp!ÆB(a>˗/|/_|/| ̗/|`>g0|`|/_>aw0|;`>g0|'0_ /_| G0_&N8q"|'Noĉ'N8qD&*g0D 0_>M`0_>Moĉ'F7q&N8qĉ'No|Mt`̗o| h0| $H A /,h „ 2l`6Ç>|Ç =t`;/|`|=T`| C/Ç{ÇÆ>|Ç>|a|S/_|̗` ̗Oa| {`|>|C>|0Ç>|Ç2a>>a|˗Oa|˗a !̗`||=|Ç{a|>|Ç>|0C {p @8p |70/_| 'P G A G|/_| /_| $H? O@ DPB *O@ DPaA$XA .dC%N0 <8?8`A'p  ? 0 'p  HA H`>'p 8`A'p "Lp!ÆB(q"Ŋ/b̨q#ǎ? )r$ɒ&OLr%˖._Œ)s&͚6o̩s'Ϟ> *t(ѢF"Mt)ӦNB*u*ժVbͪu+׮^ +v,ٲfϢMv-۶n+w.ݺvͫw/߾~,x0†#Nx1ƎC,y2ʖ/cάy3΅;;PKrPKFJOEBPS/img/pc_81023.gifO-GIF87a?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JQE'0_|G=z(|E1ѣG=1_|˗/|O`>'0_|/|/_|G=z|/߿|/_/_'0|˗/߿|/_G=za| '0_>/|+/_| /_ѣGm0O/߿ O|O` '0| H*\ȰÇ#JHŋ3jȱ#|/߿|/_/|O`>˗_| ѣG=zѣG=J̗o`|˗o`| '0|/_|O`| 70G=zѣG=z1|=zG=zѣG <0… :|1ĉ+Z1ƍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3Ν<{ 4СD=4ҥL:} 5ԩTZ5֭\z 6رd˚=6ڵlۺ} 7ܹtڽ7޽|O@ DPB >QD-^Ę!,h „ 2l!Ĉ I(QD%J(QD%Jx0D%J(Q$J(QD%J(QD%J%J(QD$J(QD%J(QD%J$XA .dC惘/|[0@ H*\ȰÇ#JHŋ˗#F1bb|˗b|È#F1bĈ|È#F!惘/_/_˗/_|/_|˗`|˗/߿| O| H*\ȰÇ#JH"|hѢE-1_|'0| ̗_|/߿|˗_|/߿|O`|ϢE-ZhѢE˗ϢE-Zh0|˗/|O`'P߿|_70߿_>$XA .dC%NXb|YhѢE 0#_/߿ O|O`/_| '0,h „ 2l!Ĉ'R1_|,ZhѢEAO|/߿߿|'? ̗/߿|/߿| '0|'p "Lp!ÆB(q"Ŋ˗ϢE-Zh0|/|O`W0|#/_| ̗/_>ϢE-ZhѢE˗ϢE-Zh0EhѢE-ZhѢgѢE-Z4ϢňgѢE-ZhѢE˗ϢE-Zh0E-ZhѢE-Zh_|YhѢE hѢE-ZhѢE-˗/_>-ZhѢ|-ZhѢE-ZhѢgѢE-Zd@8`A&TaC!F8bE1f4/_|5jԨQ#|5jԨQF5j81_|4jԨQF4jԨQF5jԨqb|iԨQFiԨQF5jԨQ|ӨQF ӨQF5jԨQƉ˧QF5`>'8p?GP࿁#߿8`A&TaC!F8b|XbŊ+61| '0_>`_o`/|O`+VXbŊ#˗/_Ŋ+VXao`>˗/|0|O`|g0|˗/_Ŋ+VXbŊ˗bŊ+V0_| /߿|˗o`> W0߿| '0| /|o`>*VXbŊ+V/_|+VXbņ'p  /|O`O` 70| '0| '0|/,h „ 2l!Ĉ'R/_|+VXbņ 'p`GP  ̗/_>˗_|'p#? H*\ȰÇ#JH1b|UXbŊXbŊ+VXbŊ+B̗/_+VXb|+VXbŊ+VXbEWbŊ+VlbŊ+VXbŊ+V1_|*VXbŊ UXbŊ+VXbŊ!˗/_Ŋ+VXa+VXbŊ+VX"|XbŊ+61_|70_|˗O |7߿O@ O@ DPB >QD˗/E-Zh`>W0|˗/|O`b>-ZhѢE-˗/_>-ZhѢ| W0|S`c |8`A&TaC!F8bgѢE-Z4/b| W0|;/_| /_|̗ϢE-ZhѢEgѢE-Z4/bO`>'0_| o`{`>gѢE-Zhb|hѢE-1_>O70߿'?7p G_|˗/| <0… :|1ĉ+˗/_>-ZhѢ|-ZhѢE-ZhѢgѢE-Z4ϢE-ZhѢE-Z/_|,ZhѢEYhѢE-ZhѢE˗/E-Zh`>-ZhѢE-Zh|hѢE-1_|/_   <0… :|1ĉ+Z/_|/^x| /| W1ŋ/^xŋ-˗/ŋ/^h1_|˗/|1W`>O? H*\ȰÇ#JHŅwŋ/Z1| /_|̗ŋ/^xŋ ˗ŋ/^/b/߿|=W0|xŋ/^x"|xŋ-擘/_>`>8`>'0_|/_>$XA .dC%NX|xŋ-xŋ/^xŋ˗/ŋ/^h1ŋ/^xŋ/^0_|.^xE.^xŋ/^xńwŋ/Zwŋ/^xŋ/&̗/_/^xb  '0_|˗/|#08`A&TaC!F8bE˗ŋ/^bO`0O| H*\ȰÇ#JHEwŋ/Z1_> /| /_> xŋ/^x|xŋ-拘/_|˗O`|/߿|˗/| ̗/_> +ŋ/^xŋ˗ŋ/^ŋ/^xŋ/^L/_|/^x|/^xŋ/^xb|xŋ-x`X0_/^xŋ ˗ŋ/^Ob|.^<0'p  <0… :|1ĉ˗/_Ŋ+VXa(0| /߿|囘bŊ+VXbńWbŊ+Vl/b|˗/|/|˗/| ̗/_>0|/_|˗O`| O'p "Lp!ÆB(q"EWbŊ+Vlb>/_|/߿|70| 0| G`> _@$XA .dC%NH0_|*VXbŊ E'0_˗O`'0| '0߿|0| G0_> '0_XbŊ+VX`|UXbŊ拘/_|˗|O| '߿ '| H0_|˗_|˗o`|O o`  <0… :|1˗"E)RH1Ł(RG"E)RH"E ˗/E)RHb>G1b|)RH"E)RH`|QH"E)H"E)RH"E)R\/_|)RH"E(RH"E)RH"E˗/E)RHb>)RH"E)RH"ŅG"E)R"E)RH"E)RHqa|QH"E)0+_| H| H*\ȰÇ#JHŇwŋ/Z1| /| W1ŋ/^xŋ˗/ŋ/^h1_| '0_#/_>˗/? O? H*\ȰÇ#JHłwŋ/Z1߿|70߿|1|xŋ/^x|xŋ-拘`>O`3`|]xŋ/^x`|]xŋA̗/_>0̗/|/߿|8`A&TaC!F8bE˗ŋ/^ŋ/^xŋ/^L/_|/^x|/^xŋ/^xb|xŋ-xŋ/^xŋ˗/ŋ/^h1ŋ/^xŋ/^0_|.^xE.^xŋ/^xńwŋ/Zw/^xŋ/&̗/_/^xb/^xŋ/^x1a|]xŋ]xŋ/^xŋ ˗ŋ/^ŋ/袋.袋.(!  <0… :|1A$XA .dC%NXE'p "Lp!ÆB`> 4xaB 6tbD)VxcƄ H*\ȰÇ#&O@ DPB >QD-^Ę1!,h „ 2l!Ĉ'Rh"ƌ7r#Ȑ"G,i$ʔ*Wl%̘2gҬi&Μ:w'РB-j(ҤJ2m)ԨRRj*֬Zr+ذbǒ-k,ڴjײm-ܸrk'p "Lp!C H@$XA .dx? 4xaB8`A&T!B$XA .dC'p 8`A&T_>8` H*\o… O@ 'p "Lpa .\p… .\0!|,8? 4xaB ˗@$Xp ,h „ ˗/… .0 O@ DP|[p… .\p… 'p 8`A&T_|O@'p "Lpa|-\p H A$XA .̗/… .\p… .\x`>  <0…p |,8? 4xaB ˗o… O@ 'p "Lpa|.\p… .\pƒ H H*\/_| 'p`#8? 4xaB ˗o… O@ 'p "Lpa|.\p… .\pƒ 8?8`A&T_|O|GP ,h „ ˗/… .0 O@ DP|-\p… .\p…8PO@ DPc8`> H*\/_| .\|,H?'p`8`A 80_>$H $H |'p "Lp!ÆB`> #8? 4xaB ˗@ H*\/_| .\| /߿'p|˗/| ̗/_0@ HO@ DPB >!|Gp ,h „ ˗/Á ߿ 'p "Lpa|-\p ('p|/_ ̗O`|/_$H AO@ DPB >!|Gp  O|'p  ;x|<`>G`>O|'p  ;x |;xO@#(?G0_>/@'߿8`A <0… :|1"B$@$/| $H| $H`|$8`>8`>8P`|$H A$H A˗? 4xaB8P࿁ O̗O`'p ? 480_| H*\ȰÇ#"O@'p |˗/|˗/_>0@ H;x|,8?G0_|˗O`| ̗/@ O@ ̗/_$XA .dC'p 8`|/߿|'0_/_$H A#H@$Xp  ̗`|/|/|/A $/_|8`A&T`> $#/|̗/_'`>8`A <0… :|1"B$Xp ̗`|'0_>˗/_ G A ˗ A8` (0_> /|`>? 4H0_|0'߿8`Aw?$Xp  ̗`|7`> ߿| HAw<0 O@ DP|-\p… .\p…8` H0_> /|O` ̗ A ̗/A'p 8P`|_ '0| ̗ A /_| H*0 O@ DP|-\p… .\p…8` H0_> /|/_|(? 480_|wA̗O`˗/|0@ HAw<0 O@ DP|-\p… .\p…-\p… ˗o!| .\pB˷p… [p… ̗/… .\p… .\x0… .\`|̷p… .4/_| .\_ .\p|-\p… .\p…-\p… ˗o!| .\pB˷p… [p… ̗/… .\p… .\x0… .\`|̷p… .4/_| .\_ .\p|'p "Lp!ÆB0D%2̗/|%J0_|$J(0D%2̗/D%J(Qb|%J0_|I(Q|(Q|%J0_|%J(QDI(Q"|='QD ˗ODI(Q"|I(QD%F'QD 0D%.̗/_>% 'QD 'QD%J1D%2̗/|%J0_|$J(0D%2̗/D%J(Qb|%J0_|I(Q|(Q|%J$C <0… :|1"|%J0_|I(Q|(Q|%J0_|%J(QDI(Q"|='QD ˗ODI(Q"|I(QD%F'QD 0D%.̗/_>% 'QD 'QD%J1D%2̗/|%J0_|$J(0D%2̗/D%J(Qb|%J0_|I(Q|(Q|%J0_|%J(QDI(Q"|='QD ˗ODI(D O ,h „ 2l!ĈI(Q"|='QD ˗oa|s/|%J0_|%J(QDI(Q"|='QD ˗oa|s/|%J0_|%J(QD̗/߿|˗|'p 4hРAg| 4hРA 4h`|4hРA ϠA 4hРA ̗/,h „ 2l!Ĉ70| 70ā$J/_ ˗_|`>8`A 4hРAgРA 4hP`/|O@$X`> 4hP`|8`A&TaC!FD`˗o`|#/_|(?'p ˗ _>僘`>Id/_ _|˗a 8߿ O@ ̗/_`>O ,h`|8`A&TaC!FD`/߿|9g0_|哸0_|70|1_|哸0_|$J(0|'0߿|g0_> 'QD%J1| ̗/_ ̗/|/߿|$H A#H|_>70A#/AG A ̗/_>$XA g0| ̗_g0_|[`|.\p… .\pƒ.\p…˷`/_|8? #/_|˗o`|#H A˗/,h „ ;/_`>8`>/_|/A $H0_| H*\ȰÇ#"'QD 0D%.̗/_>% 'QD 'QD%J1D%2̗/|%J0_|$J(0D%2̗/D%J(Qb|%J0_|I(Q|(Q|%J0_|%J(QDI(Q"|='QD ˗ODI(Q"|I(QD%FW0_(Q|=W0_(Q|(Q|a>%*̗/D%J(Qb| ̗a>$XA &̗/B /| .\0a|-\p /| .\0a|.\p… .\pƒ _|0@ ?'p "L(0_| 3o`|`>70߿ O@ DP`|)TPB _|0@ ?'p "L(0_| *TPB *TPB/߿| '0A@$XA ˗Oa|/߿| W`> <0!|SPB/߿| '0A@$XA OB *TPB *T_>O`>g0_|*Ta|g0| '0_| ˗/B "̗/_> *Th0| '0|3/_| *T0_| *TPB *TPB̗O`|˗O`| ̗/_˗OB ˗Oa|/߿|/_|˗O`|SPƒ˧PB +/|˗/|/_|/B ̗/,h „ 2l!ĈI(Q"|='QD ˗ODI(Q"|I(QD%F'QD 0D%.̗/_>% 'QD 'QD%J1D%2̗/|%J0_|$J(0D%2̗/D%J(Qb|˗OD0āI(`|I(Q`>'QD(QD%J`|惘OĄ{`|˷0|%>̗/_>% w0_| A'Qb|I(QDI$QDO| 8P`/,h „Kh0|%a &Lh0_|&L0aB /| K0a„K0a„ &L0a„ &L0|̗/_>˗/A <`|g0|˗O |70߿70,h ‚˗0a„  g0_|˗`G`>'p "4/_ &L0a„ &L0a„%'`>߿@8`A&̗/_B _'0_|+0 H ˗/_„ &L(0_|8߿8߿| ? 4xa|%L0a„ &L0a„ &D`>˗`>W0_„ &/_B __| W0_ &D/_| &L0| ̗_| ̗`&L0a|&L0a„ &L0a„ "g0_|˗/@ 70߿ o`> 7P` 8p˗o8_|˗/@ 7Po`@7p/_| H*`| ̗/_> o`| o|8p̗/,h „ 2l!ĈI(Q"|=0D!˗/D(QD(QD%JOD˗a(Q|(Q|%J0_|%J(QDI(Q"|='QD ˗ODI(Q"|I(QD%FW0_|;/|I0_|̗/߿| 70|%>̗/_>% W0_|;/|I0_|%J(QD70| ̗a>˗a>?'P@8`A&4/_| *T`>#o`>!̧PB ˗OB *TPB *T_>/_| ̗/߿|'PO? Hˇ`>/_| /_O 8`A /B"D0| ̗/_>˗_|(߿'@$XAO@ DPB >a>O`>_>#0 <0_|3o`_O` @$XAˇ!B"g0| '0߿|'0|8߿8`A˗? 4xaB 6tbD O`>_>#/|1_|70߿| 70| W0_'1b|I(Q`>O`>O`g0_|$F̗/D%J(Qb|70_'0_70_|˗/|'b|;/_>˗/_> ̗/_>70_|/_>˗OD̗/|˗/|˗/|/_|0_>$XAO@ DPB >a>%Jd/_$J(qa|I(Q`>%Jd/_>%J(QĈ$J(a|(Qą'QD$J(a|$J(QD#(QD{OD˗/D(QD(QD%JOD˗a>%J\/_|%JOD˗OD%J(1b>%Jd/_$J(qa|I(Q`>%Jd/_>%J(QĈ$J(a|(Qą'QD$JH"'? 4xaB 6tbD$J(a|(Qą'QD$J(a|$J(QD#(QD{OD˗/D(QD(QD%J0 <0… 'p H*\P!,h „ 'p "Lp!C H*\ȰÇ#.O@ DPB8`A H*\!,h „ 'p "Lp!à H*\ȰÇ#.O@ DPB8`A H*\!,h „ 'p "Lp!à H*\ȰÇ#*O@ DPB8`A H*\!,h „ 'p "Lp!C H*\ȰÇ#J0_>)R/E)RH`|)RH"E)Rx0_>)R/E)RH`|)RH"E)Rx0_>)R/E)RH`|)RH"E)Rx0_>)R/E)RH`|)RH"E)Rx0_>)R/E)RH`|)RH"E)Rx0_>)R/E)RH`|)RH"E)Rx0_>)R/E)RH`|)RH"E)Rx0_>)R/EQDEP| H*\ȰÇ#JH"D$XA .dC%NXQ",h „ 2l!Ĉ'R`> 4xaB 6tbD)V <0… :|1ĉ+Z1Fmܸqƍ7nܸqƍ7n܈0_7nܸqƍ7nܸqƍ˷qƍ7nܸqƍ7nܸq#|6nܸqƍ7nܸqƍ7nD/ƍ7nܸqƍ7nܸqƍ۸qƍ7nܸqƍ7nܸa|7nܸqƍ7nܸqƍ7"̗oƍ7nܸqƍ7nܸqFmܸqƍ7nܸqƍ7n܈0_7nܸqƍ7nܸqƍ˷qƍ7nܸqƍ7nܸF/,h „ 2l!Ĉ'Rh"ƌ7rc|?~Ǐ?~ǎ}Ǐ?~Ǐ;Ǐ?~Ǐ?~/Ǐ?~Ǐ?~c|?~Ǐ?~ǎ}Ǐ?~Ǐ;Ǐ?~Ǐ?~/Ǐ?~Ǐ?~c|?~Ǐ?~ǎ}Ǐ?~Ǐ;Ǐ?~Ǐ?~/Ǐ?~Ǐ?~c|?~G}G}G/,h „ 2l!Ĉ'Rh"ƌ7rc|?~Ǐ?~ǎ}Ǐ?~Ǐ;Ǐ?~Ǐ?~/Ǐ?~Ǐ?~c|?~Ǐ?~ǎ}Ǐ?~Ǐ;Ǐ?~Ǐ?~/Ǐ?~Ǐ?~c|?~Ǐ?~ǎ}Ǐ?~Ǐ;Ǐ?~Ǐ?~/Ǐ?~Ǐ?~Q#|O@ DPB >QD-^ĘQF=ZO@ H*\ȰÇ#JHŋ3jȱG ? 4xaB 6tbD)VxcF9v`>8`A&TaC!F8bE1fԸcG(? 4xaB 6tbD)VxcF9v1_|>~Ǐ?~ǏǏ?~Ǐ?~/Ǐ?~Ǐ?~c?~Ǐ?~Ǐ?~Ǐ?~Ǐ?~Ǐ?~Ǐ?~Ǐ?~#|,h „ 'p "Lp!ÆB(q"Ŋ/b̨q#G:vcǎ;vرcǎ;vܘO |,h „ ? 4xaB 6tbD)VxcF9n/_Ǎرcǎ;vرcǎ7#|uرcǎ;vرcǎבc:vرcǎ;vرcǍ1߿|;vرcǎ;vر|u_;vرcǎ;vqc:r/_ǎ;vرcǎ;v1߿|9cǎ;vرcǎ;vܘ_ױcǎ;vرcǎ;n/_Gرcǎ;vرcǎ7#|uرcǎ;vر:|'p "LP`8`A&TaC!F8bE1fԸ|u_;vرcǎ;vqc:r/_ǎ;vرcǎ;v1߿|9cǎ;vرcǎ;vܘ_ױcǎ;vرcǎ;n/_Gرcǎ;vرcǎ7#|uرcǎ;vرcǎבc:vرcǎ;vرcǍ1߿|;vرcǎ;vر|uԘO`;vcǎ;vqc H*_>$XA .dC%NXE5n1_ǎuرcǎ;vرcǎ O@ DP'p "Lp!ÆB(q"Ŋ/b̨q#Ǎ1߿|;vرcǎ;vر|u_;vرcǎ;vqc'p #H? 4x0߿| H*\ȰÇ#JHŋ3jqc3_>3c:vرcǎ;vرcǍ0$ A$X|'p "Lp!ÆB(q"Ŋ/b̨q#Ǎ1߿|;vرcǎ;vر|u_;vرcǎ;vqc:r/_ǎ;vرcǎ;v1߿|9cǎ;vرcǎ;vܘ_ױcǎ;vرcǎ;n/_Gرcǎ;vرcǎ7#|uرcǎ;vرcǎבc:vرcǎ;vرcǍ1߿|;vرcǎ;vر|u_;vرcǎ;vQG_>$XA  /,h „ 2l!Ĉ'Rh"ƌ7rܘ_ױcǎ;vرcǎ;n/_Gرcǎ;vرcǎ7/_Gرcǎ;vرcǎ70 <0O@ DPB >QD-^ĘQFu80_ǎ;vرcǎ;v1G$XA <0… :|1ĉ+Z1ƍ7㘏c:vرcǎ;vرcǍ8o`;vرcǎ;vqc> H? 4xaB 6tbD)VxcF9nױ|;vرcǎ;vر|;ױcǎ;vرcǎ;nױ|;vرcǎ;vر|;ױcǎ;vرcǎ;nױ|;vرcǎ;vر|;ױcǎ;vرcǎ;nױ|;vرcǎ;vر|;ױcǎ;vرcǎ;nױ|;vرcǎ;vر|;ױcǎ;vرcǎ;nױ|;vرcǎ;vر|; <0… :|1ĉ+Z1ƍ7q`;vرcǎ;vqcرcǎ;vرcǎ70 <0B'p "Lp!ÆB(q"Ŋ/b̨q#Ǎ:vcǎ;vرcǎ;vܘcǁ:vرcǎ;vرcǍ:vcǎ;vرcǎ;vܘ|,h „  <0… :|1ĉ+Z1ƍ7q`;vرcǎ;vqcرcǎ;vرcǎ7q`;vرcǎ;vqcرcǎ;vرcǎ70 <0B'p "Lp!ÆB(q"Ŋ/b̨q#Ǎ:vcǎ;vرcǎ;vܘcǁ:vرcǎ;vرcǍ:vcǎ;vرcǎ;vܘcǁ:vرcǎ;vرcǍ'p "L| H*\ȰÇ#JHŋ3jqcرcǎ;vرcǎ7q`;vرcǎ;vqcرcǎ;vرcǎ7q`;vرcǎ;vqc H*$/,h „ 2l!Ĉ'Rh"ƌ7rܘcǁ:vرcǎ;vرcǍ:vcǎ;vرcǎ;vܘcǁ:vرcǎ;vرcǍ'p "L| H*\ȰÇ#JHŋ3jqcرcǎ;vرcǎ7q`;vرcǎ;vqcرcǎ;vرcǎ7q`;vرcǎ;vqc H*$/,h „ 2l!Ĉ'Rh"ƌ7rܘcǁ:vرcǎ;vرcǍ:vcǎ;vرcǎ;vܘcǁ:vرcǎ;vرcGu/_ǎ;vرcǎ;v|,h „ 'p "Lp!ÆB(q"Ŋ/b̨q#ǎyܘϣG=zѣG=z|=zѣG=zc|7ѣG=zѣG#'p "L ,h „ 2l!Ĉ'Rh"ƌ7r#Ȑ"G,i$ʔ*Wl%̘2gҬi&Μ:w'РB-j(ҤJ2m)ԨRRj*փ  <0… :|1ĉ+Z1ƍ;z̘/|}Ǐ?~Ǐ170|0@ 70߿8`A&TaC!F8bE1fԸcG O O? H*\ȰÇ#JHŋ3jȱ ?? ? 4xaB 6tbD)VxcF9vX`>? ? 4xaB 6tbD)VxcF9v/|O`/|yѣG=zѣG!'P߿o`'p "Lp!ÆB(q"Ŋ/b̨q#ǎ? )r$ɒ&OLr%˖._Œ)s&͚6o̩s'Ϟ> *t(ѢF"Mt)ӦNB*u*ժVbͪu+׮^ +v,ٲfϢMv-۶n+wnр;;PKԦOOPKFJOEBPS/img/lobread.gif)GIF87aP?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,P H*\ȰÇ1bĈ#F1bĈ#F1bĈ#F1bĈ#F1!|,h ‚ H*\ȰÇ#JHŋ3jȱǏ -˗/$| 2dȐ!C 2dȐ!CR̗/$|B 2dȐ!C 2dȐ!%Ra|!C 2dȐ!C 2dȐC/_H 2dȐ!C 2dȐ!C>̗a|!2dȐ!C 2dȐ!C 0_> (?˗O`|'pO ,h „ 2l!Ĉ'Rh"ƌ7r#Ȇ̗_|˗`|/__| ̗/dȐ!C 2dȐ!C a| ̗o`/߿|/_>2dȐ!C 2dȐ!C `>(0|8_>˗/߿|`>0 < ,h „ 2l!Ĉ'Rh"ƌ7rc̗O`|;O`|'0߿|o`|Ǐ?~Ǐ?vG0_> (?0_@$XA'p "Lp!ÆB(q"Ŋ/b̨q#ǎ8`A8|+X` ,/_ ,X`A8`A&TaC!F8bE1fԸclj.c`|8? 480_$XA .dC%NXE5nqb;/džy|ϣG=zѣG=zH0| ̗/Dž0G=zѣG=z`> O@ 7p/_>$XA˗0a„ O@ DPB >QD-^ĘQF'C/|1̧`> 4xaA$XA O@ DPB >QD-^ĘQF'C/_c#|-ѣG=zѣG= /|a>c|=zѣG=zѣǁ̗_+`>=&ѣG=zѣG=fO@ `>8 A$XA .d!|,? 4xaB 6tbD)VxcF9^w0߿|O`> 3cǎ 9̗cǎ;vرcǎ;v`> #O`>;cǎ Aױcǎ;vرcǎ;N̷0| -O@$X |,h „8| ? 4xaB 6tbD)VxcF9N̷0| %O H |'p "L(`>8`> ? 4xaB 6tbD)VxcF9J̷0| ̗/|1̗/_njC/b;vرcǎ;vQb.c`| S/_G;/b;vرcǎ;vQb.c`| C/_| +`>1_ǎ;vرcǎ;v(1|1g0_|3a ;/|uرcǎ;vرcǎ-O@ O@#/_ ˗| ˗/| ̗/߿|70߿| ̗_/_|˗/|+X| H*\ȰÇ#JHŋ3jQb̗a| w0_/_>W0_/߿|_|˗_|/|uرcǎ;vرcǎu/|G0߿| ̗o`|3_>'0| /_| ̗O`|uرcǎ;vرcǎu/_|8P '0_˗/߿|O`|'0? _o@$X`>$XA .dC%NXE5n(1_nj#_˗_|`| /|˗O`o`|uرcǎ;vرcǎu̘/|O`/_>/|(_߿|@$XР| H*\ȰÇ#JHŋ3jQbk/|:v$c;vرcǎ;vQbk`|8? 4x`|" <0… :|1ĉ+Z1ƍ%1_!̗cGaױcǎ;vرcǎ;JQc|˗0_˗1_ǎر|;vQ |,h „ 'p A ,X` ,/_|˗`|,X` ,X0_| ,X_'p O@$XA8? 'p 8 |,h B H`>'p H ,h „ 2la60Ç˗/|k/_|>$0@ HAww;(0_|w`|/_g0Ḃ0_|C(0_| ̗/|"Dh0|˗|!"D!B"Dh0B"DP`>O@ DPB >a>$.g0D˧0_>80_$J`| C/I(QDO@ O| /_/O@ DPB >a>+/_g0|(߿߿808p| ̗o(0_ `> ߿߿(08p|//_>$XA .d!|'0| G0|O`>{Ç>|| G0| ̗`>O`> '0_k/|G0_>+o`>/| 3/_|{h0_>|a> 3_>#`+_>3Ç>|Ç!'0|/| 3`g0_| W0| 3/|3/_> oO|7P`(0߿|7P`80 '0/_(0_>$XA .d|g0_K/_ Oa>{Ç>||` O`>`+/߿| W0|s`/_O``` ̗`>0_>3O |@ <0… .̗ |'߿'p ||$(0 <0… :|1ā+/|`>(0@ `>(߿| o|8p`8p`| /|7_|˗/_> //߿| o|8p`80_8p`|O@ DPB 8 A7p`/_7p H*\ȰÇ#JH?| G| O? ߿(`>'p (?˗/߿|'0 (?#/|_G| O@8P O8p | O@ DPB ``70|/|9tСC:tСÁ;`70_|w0|̗o`W0_|9G0߿| _>`W0| ̗_W0|k/|70_˗`>:tСC g`>/?O|`>   <0… :|1D;/_|˗O`|70| ̗|_'p`˗o|70| O/߿/߿?#/|˗/|| ̗|70|˗_>#/_8`A&TaÆ:tP`>:tСC:t0C!|5̗`|g0C ̗a9:ϡC:tСC*|9t0|w0_> 3ϡC˷0_>9,/C:tpa>:ϡC:tСC*|9t0|)̗a|w0C ̗oa|sX0_>:t|:t(0C:tСC:Tϡ'p`>$XA˗a|˗!!̇!B!̗| ̗/ƒC!B"D!B!D!BO@ DPB >QD(&g0E˗`|˗b|(1_|̗/|5̗/E)R\0 <0‚ H*\ȰÇ#J(`> 4xp 'p "'p@$X`> $8`AO@ 8? O@8`A&TaC!F8bE1fԸcGAv <0… :|1ĉ+Z1ƍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3Ν<{ 4СD=4ҥL:} 5ԩTZ5֭\z 6رd˚=6ڵlۺ} 7ܹtڽ7޽| 8 O@ O@˗`8`AO@ DPB >Q |,h BO@ D /_| ,0  <0… :|1Ĉ&̧`>'p A  8`A&TaC!B1b>"FtO!|O@(? 0 H*\ȰÇ#Jto"|g0_| 7q|M8qĉ%0|'*̇0_|˷0_|˗oĉ'N8qb| C/_|7qb|&N8qĉM|`;/_%̗/DM8qĉ'Nda|8? /_ ̗o@'p  'p "Lp!ÆBl`0_> 7p`(`>_ o|@/˗o@ 7p@8p'p "Lp!ÆB(qa>̇0|w0_ 0|&N8qĉ̗O`|O`>+` +/| ̗O`+`| ;/| 0_'N8qĉ !̗/|̗`>W0_|/_0@7'p "Lp!ÆBd`|/_#o` ;` /_>o` g0|̗/_>/_|'0_|1bĈ#Fa>/| '0_ '0_|/_|+/߿|_>'0߿|E1bĈ#&'0|/|70_|w0_|/߿| 70_| 0|+/߿|O`_|߿|8`A&TaC!F0߿|o`>a|W0_>Ko`/|`'N8qb|/߿| '0A O|7p|'P|/߿߿'P`7p/_|_>/_>o| H*\ȰÇ#J08|?'p@$H`>'p`|/ /߿|8p|G`>$XA .dÆ (?˗_|`O@ /'0_'0|08 A@O`>'p|O@ <0… :|1|̗`| ̇0_|+/__|+/߿|__>̗OD%J80_>̗O`|` +/|'0_>'0|W0_> ˗`|'0|'0߿|̇0_>%J(QD`>C`g0_3/_>˗`|O`|˗O`|)'QD%J̗`O`| 'P`> /@(P|0@/߿߿? _80_7P`| ̗/_>/_>/_ <0… :|1b| I,`| 'Qb| I(QD)'b>$Jd`| 'b| I(QD%6̷0Ă 0|"'p ,hp`| O@ DPB >$oa>3"D 0_A/_ B"D!6̷0ă˷0_>A0_ B"D -|A1|w0_>c"D!B"| A<`| K/D k"D Aa B`>!;/|a|A"D!B\a>!̗/|)̗/D 0B$X H`>'p H H| 3hРAgРA 4Ϡ| ̗`|4h|4(0,h „ 2l!Ĉ1'`'0_|'P ,hA O@,/_ ,80_A+/_˗` ˗` ` $| ,X`+H0_|˗/_˗`˗/_O@ DPB >Q`> HA H|O@'p ", g`> 480A3/_| ˗ϠA˗ϠA O@ D HO@80,`> 4h? ? 4xaB 6tbD$J(QD-'a-̗a|0D%J(QDI(QD%.'QD%Joa|/A#H0_>O`>G | H*\ȰÇ#J\oĉ'N8q`'N8a/| 70|k/| SO`>-7qĉ'N8qa'N8q|M8qĉ'0|o`> +o`>g0_W0_|0߿?'p "Lp!ÆB(a&N8qĉ7qĉ'Nw0߿| /߿| W0_|˗a|g0_'0߿|'0߿|G0|'N8qĉ;oĉ'Nh0_|&N8qĉW0__+`9̗`| /| ̗/|W0_|&N8qĉ'F̗/_|'N8qbC$XA .dC'p| ̗o`>G| O@8p _>0'p |,h „ 2l!Ĉ'JO@ DPB >"D!B|'0|o`|/_/|O`˗O` G0D!B"D!"D!B0D!B"Ăo`˗/|3`| ̗`| ̗/_/_> 70D!B"D!"D!B"D!Bb>3/_| b|!B"D!B"D!B"D!B"|!(˗ $/A $HP`| H*\ȰÇ#JHŋ3jȱG> w0_!̗c|?~Ǐ?~G> ̇0_)̗/|}Ǐ?~Ǐ;(0_|̗/|a̗/Ǐ?~Ǐ?~#|,hA$08`A$X`A$XA .dC%NXE5nG'p "Lp!ÆB(q"Ŋ/b̨q#ǎ? )r$ɒ&OLr%˖._Œ)s&͚6o̩s'Ϟ> *t(ѢF"Mt)ӦNB*u*ժVbͪu+׮^ +v,ٲfϢMv-۶n+w.dݺvͫw/߾~,x0†#Nx1ƎC,y2ʖ/cάy3Ξ?-z4ҦONz5֮_Î-{6ڶoέ{7޾.|8Ə#O`@;;PK$v))PKFJOEBPS/img/pco81050.gifa^GIF87a]?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,] H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJU'0Վ  '0,h „ 2l!Ĉ'Rh"ƌ7r1|ѣG ̗b>˗O`|yѣG=zѣG˗O`> ̗/|/_>=O'/߿?'p "Lp!ÆB(q"Ŋ/b̨q#ǎ /@߿|O@ DPB '0_ o`߿|| H*\ȰÇ#JHŋ3jȱ#|/|O`|/G '0_ /_>'0| ̗O`|=zѣG=zE O߿'p "Lp!Æ/|/_|˗O`> ̗/_>$XA .dC%NXE5n1c>=zѣG=zѣG=z$? 4xaB 6tbD)VxcF9vdH#I4yeJ+YtfL3iִygN;yhPC5ziRK6ujTSVzkV['p "Lp!à HO@ DP‚ H*\ȰÇ#JHŋ3j(1_>9˗c|96̗#G9rȑ#G9r#G81G ȑ#G9rȑ#Gȑc|8NǑc|8rȑ#G9rȑ#G8rX0_>q0_>9rȑ#G9rQ`>9̗|96̗#G9rȑ#G9r#G81G ȑ#G9rȑ#Gȑc|8NǑc|8rȑ#G9rȑ#G8rX0_>q0_>$XA .dC%NXE5n? O@,X` W` ,XP` ˗/_ ,X`'p "Lp!ÆB(q"Ŋ/b̨q#|/GqL/| ̗c|8rȑ#G9rȑ#G8G0| ̗/|˗O`|q/DŽg0|˗_|˗/|q̗#G9rȑ#G9r|˗O`| ̗/| _|'pO@˗O`>_|70_ /,h „ 2l!Ĉ'Rh"ƌ7B_>'P࿁߿|/,h?$XA ? /߿|(_>̗/,h`| H*\ȰÇ#JHŋ3j1/_> '0_| '0 H_>$80_>/_>'0߿|,X`A'p "Lp!ÆB(q"Ŋ/b̨q#|'P_߿| HC!‚g0B |o'p   <0… :|1ĉ+Z1ƍqo`>0_>*`>8`A&TaC!F8bE1fԸb>a|'櫘#B$8? 4xaB 6tbD)VxcF!ȑc|8N"|,(? 4xaB 6tbD)VxcF)ȑc|8Nq"| <0… :|1ĉ+Z1ƍqȱ`|'`>'p "Lp!ÆB(q"Ŋ/b̨q#ǃ:v(0_u\08`A&TaC!F8bE1fԸ|;v/_G:O H*\ȰÇ#JHŋ3ja; ̗|'p@$XA .dC%NXE5n(1_ǎQb (? 4xaB 6tbD)VxcF9^̗cǍQb 8? 4xaB 6tbD)VxcF9nO@ DPB 8`A&08 |$ <0… :|1ĉ+Z1ƍ;O@ DPB8`A&,0 , <0… :|1ĉ+Z1ƍ;z/Ǐ 'p A H*\ȰÇ#JHŋ3jȱǍ}Ǐ?~Ǐ?~a|?~Ǐ?~Ǐ?~t/Ǐ?~Ǐ?~ǏǏ?~Ǐ?~G}Ǐ?~Ǐ?~a|?~Ǐ?~Ǐ?~t/Ǐ?~Ǐ?~ǏG HO@ DPB >QD-^ĘQF ѣLj  <0| H*\ȰÇ#JHŋ3jȱ|=2̗E O@ DPB >QD-^ĘQF H*\0,h „ ˷p… ˗? 4xaB 6tbD)VxcF-˗/G˗#|8n̗/G9rȑ#G9r0G1c>Ǒ#G9rȑ#G9&Ǒ#ǂqĘ|qȑ#G9rȑ#G qȱ`|/1_|9rȑ#G9rqa˗O`|ȑc|8Z̧0| i̗#G9rȑ#G96/_ ̗o`>8rX0_>-G0_|Ǒ#G9rȑ#GO |O@ DPB kذa| '0_|/_|  <0… :|1ĉ+Z1ƍ/|coƍX1C'߿|/߿| HO@ DPB >QD-^ĘQ'p@$(0_ ,H0_| ` ,80_ ,X`,(0| '0_|,X |8`A&TaC!F8bE1fԸQ`X0_>-Qa|Ka>'0߿|w1_|9rȑ#G9ra>;c|70_|˗c|8&̗/| '0_|(@$X|'p "Lp!ÆB(q"Ŋ/b̨qD߿| H̗O`/|"D/BO@  <0'p "Lp!ÆB(q"Ŋ/b̨!|,h ‚O@ ,`o`   4xa| <0'p "Lp!ÆB(q"Ŋ/b̨!|,h ‚O@ ,/|'0߿|/|"D0 <0a'p "LP`| H*\ȰÇ#JHŋ3jl/F ߿8`A ˗/| ̗/_>ˇ!B!DaA O|`>8`A ̗? 4xaB 6tbD)VxcF H0_| ۸q#|6*̗/| ̗o|6nܸqƍ7nܸqc|6̗a7"̗o| 5G0߿|˗/|0#8߿'p "Lp!ÆB(q"Ŋ/b̨a|۸q#|6R`>_'P`>o|8`A&TaC!F8bE1f0_mܸa|+c`>o`>˗/| W0_7nܸqƍ7n0_mܸa|+c`> /_>/| '0_|6nܸqƍ7nܸq#|6:̷qFma>˗o`| `>/߿80,h „ 2l!Ĉ'Rh"ƌ˷a7"̗o| ̇1_7nܸqƍ7nܸ0_mܸa|/ۘ/_>mܸqƍ7nܸqFmtoƍۈ1ƍmܸqƍ7nܸqFm|oƍۈ1ƍmܸqƍ7nܸqƄm/_7'p ,h „)TPƒ8`A&TaC!F8bE1fԈ0_8`A&TB$XA ˧PB O@ DPB >QD-^ĘQ|6RO@ DPB8`A&T80_| .\0,h „ 2l!Ĉ'Rh"ƌ ˷qƂmܸb|7˗oƍ7nܸqƍ7̗oƍ۸qc|۸1_7nܸqƍ7n(0_7̗oƍ80,h „O@ DPB >QD-^ĘQc|5jD/F5O@ DP@$XA .dC%NXE3˧QFiԨQ#B$XA 'p "Lp!ÆB(q"Ŋ/b̈1_>5"̗OF5jԨQF5jԨQFӨQ#|4jԨQF5jԨQF5jX1_>5"̗OF'p "Lx? 4xaB 6tbD)VxcF۸qc|6n܈`>8`A&$/_| H*\ȰÇ#JHŋ3j̗OFӨQc|4j0@ H*\ȰÇ#JHŋ3j/ƍ ˷qFmܘ/_|7nܸqƍ7nܸq`|7n,/ƍ%˷q|mܸqƍ7nܸqƂmܸ`|7noF۸qƍ7nܸqƍ`> 4xaB O@ DP| .\_|8`A&TaC!F8bE1fx0_۸q#|6j̷q|mܸqƍ7nܸqFmtoƍx1ƍ˷qƍ7nܸqƍ˷a7"̗o| ˗o#|mܸqƍ7nܸqFmtoƍh1|۸0_|7nܸqƍ7nܸQa|۸q#|6V0| '0|˗/_k/_7nܸqƍ7nܸ0_mܸa|+s/_|_>߿|˗/߿8|'p "Lp!ÆB(q"Ŋ/b̨qa|۸q#|6V1_|'0|O@$(0_>$XA .dC%NXE52̗o|7nD/FG0_|'0|/_>˗oƍ7nܸqƍ72̗o|(? 4x|%LX0_ &L(0_‚ /߿70/_>$XA .dC%NXE52̗o| ̗o#|ۨ0_>6n/ƍ7nܸqƍ7nl/F(#_|˗O`| ̗/@o ,H0_> 4h_|gРA 4hP`| H*\ȰÇ#JHŋ3jl/F('P_߿|'_? /A 4`>? O@$XAO@ DPB >QD-^ĘQc|6:G1|8? '0|70߿|8? 0 <0'p W` /,h „ 2l!Ĉ'Rh"ƌ˷a> /| /_>O`/| '`> 4xa|#_|˗o`| O|߿8`A&TaC!F8bE1f0_Qg0|/_O`>˗/|˗/_>mT/_|5O'߿|߿| O`>(0,h „ 2l!Ĉ'Rh"ƌ˷aX0_ Ca>_/_| '0_|6nܸqƍ7nܸq#|6:̷q| ˷b> /|O` '0|̗oƍ7nܸqƍ72̗o|7nD/Ɗ3o`|˗/|8_?'p "Lp!ÆB(q"Ŋ/b̨a|۸q#|6V̷_0˷qƍ7nܸqƍ˷a7"̗o|˗Oc7nܸqƍ7nܸ0_mܸa|/۸Q`|7nܸqƍ7nܸQa|۸q#|6b̷q|7nܸqƍ7nܸQa|۸q#|6f̷q|7nܸqƍ7nܸ1a|۸q#|6j̷q|7nܸqƍ7nܸa|˷qF˷Qc|6noƍ7nFmFP| H'p "Lp!C H*̗OB ̗? 4xaB 6tbD)VxcF(`> 4xaB "O@ DP|-\p|8`A&TaC!F8bE1f80_7̗oƍ(? 4xaB'p "Lp!ÆB(q"Ŋ/b̨_|7n,/ƍ1'p "L ,h „ 2l!Ĉ'Rh"ƌӨQ#|4jԨ |,h „ 'p "Lp!ÆB(q"Ŋ/b̈1_>5"̗OF5jԨQF5jԨQFӨQ#|4jԨQF5jԨQF5jX1_>5"OF5jԨQF5jԨQFӨQ#|4jԨQF5jԨQF5jX1_>5"̗OF5jԨQF5jԨQFӨQ#|4jԨQF5jԨQF5jX1_>5"̗OF5jԨQF5jԨQFӨQ#|4jԨQF5jԨQF5jX1_>5"P| H*\ȰÇ#JHŋ3jȱǏ b| $H A $H A/H3/H A $H A c| AF̧0_> A $H A d|@|/_| A $H A $H0_> $H A $H 5|($H A $H AĘ/H a̗$H A $H Ai1_> ˷1H A $H A b| A̗c| A $H H D <0…cPa| H*\ȰÇ#JHŋ3jȱǏ r`> $H A $H !|@"̗$H A $H A0_>0_> A $H A $|@v̗$|@ $H A $H 1H@ $H A $H ko`>/_>򁴘/H A $H A `|˗_|oc| 5$H A $H A,/| O8`A;x4/,h „ 2l!Ĉ'Rh"ƌ7rQb|'0_> ̇1Ǐ}Ǐ?~Ǐ#0A /(? 480_|/,h „ 2l!Ĉ'Rh"ƌ7ra| Q`|q'0|>~Ǐ?~Ǐ ;/_>> g1|O 7? 8pO@ DPB >QD-^ĘQF=.̗ |'p "̗!ƒ _'߿|/߿/,hp`>$XA .dC%NXE5nѣ|'p`>$XA!D_>o`>˗o`|"/,h „ 2l!Ĉ'Rh"ƌ7ra|8`A"O@ g0|O`>;xO@ DPB >QD-^ĘQF=̗ |,h B HA /߿7߿(߿8`A(? 4xaB 6tbD)VxcF9vx0_h0_˗/Ǐ?~Ǐ?~1a| }D/Ǐ (? 4xaB 6tbD)VxcF9v0_A O@ DPB >QD-^ĘQF=2̗c|}80_|>~Ǐ?~Ǐx1_˗Ǐ?~Ǐ?~1_`>8`A&TaC!F8bE1fԸcG1_|/'P ,h „ 2l!Ĉ'Rh"ƌ7rqb|9b|}Ǐ?~Ǐ+c|#'P ,h „ 2l!Ĉ'Rh"ƌ7rb|?˗cC O@ DPB >QD-^ĘQF=b̗G`>8`A&TaC!F8bE1fԸcG`|˗/Ǐ?~Ǐ?~c|?̗@ O@ DPB >QD-^ĘQF=v̗ǃ0@ H*\ȰÇ#JHŋ3jȱǏ}0_|(? 4xaB 6tbD)VxcF9vQ`| A&̗c| $H A $H )|('P ,h „ 2l!Ĉ'Rh"ƌ7rc|@d/_>  <0… :|1ĉ+Z1ƍ;zx0_> ˗a| $H A $H 3$|˗/H A $H A rc| AJ̗ |'p "Lp!ÆB(q"Ŋ/b̨q#ǎ?2̗$ȉ0@ H*\ȰÇ#JHŋ3jȱǏ "|'p "Lp!ÆB(q"Ŋ/b̨q#ǎ?B̗$H$H A $H A/_> -$H A $H A90_> -g0_|˗$H A $H AI1_> -g0|$H A $H A91_> -g0| $H A $H A/H3O` $H A $H A/H3O`> $H A $H AR̗$H $H AH H P| H*\a| H*\ȰÇ#JHŋ3jȱǏ b| A|0 <0A$XA .dC%NXE5˗oƍ۸q#FO@ D`|'p "Lp!ÆB(q"Ŋ/b̨1_>5"̗OFӨ|'p "Lp!ÆB(q"Ŋ/b̨_|''p "Lp!Á H*$XA .dC%NXE5̗o#|۸Qc|6n/ƍ˷qƍ7nܸqƍ ˷a7̗o|7 ̗/ƍ7nܸqƍ7n4/F6n܈0_m(0_|7nܸqƍ7nܸ`|۸q#|6b̷q|mܸqƍ7nܸqFmtoƍx1ƍ˷qƍ7nܸqƍ˷a7"̗o| ˗`>惘/_7nܸqƍ7nܨ0_mܸ!|8`A&$O| ̧a> <0… :|1ĉ+Z1FmtoƍX1| ̗/_˗o |O@ <0… :|1ĉ+Z1ƅmtoc|]'0Fmoa>/_ /_>{/_7nܸqƍ7nܸ0_i̗O`|m$/Ƅ[`>`>O|80_>$XA .dC%NXE52̗o|̗/@o ,h`|/_ /_>;x0_| H*\ȰÇ#JHŋ3jd/F43/| '0߿|O`|Ә/Ƅ @8P`| /_| ̗/_>/˗/,h „ 2l!Ĉ'Rh"ƌ˷a>o`>_0 H H_>$XР| ̗_| '0| ̗_>O#|,h „? 4X0_̗? 4xaB 6tbD)VxcF 0|/__| '0߿|Ә/Ƅ ߿8 A O@ D(0_>$XA .dC%NXE56̗o|+0_ ˗`˷Qa|7nܸqƍ7nܸa|X1ƆmL/_| /_|70_|'p`? H*\ȰÇ#JHŋ3jl/F6n܈0_5O'߿|߿| O`>(0,h „ 2l!Ĉ'Rh"ƌ˷a7"̗o#| '0| '0|O`> ˷qƍ7nܸqƍ˷a7"̗oc| '0_>'0|O`>+/ƍ7nܸqƍ7nd/F6n܈0_1g0| ̗/_>'p|/O@ DPB >QD-^ĘQ#|6:̷qFmo|a̗oƍ7nܸqƍ7.̗o|7nD/F6˗/|7nܸqƍ7nܸqa|۸q#|6^̷q|6nܸqƍ7nܸq|6>̷qƃmĘoF6nܸqƍ7nܸq|6B̗/ƍ8? 4xaƒ*TP| H*\ȰÇ#JHŋ3jL/ƈ H*\P!,h „ )TPB8`A&TaC!F8bE1fԈ0_8`A&T!A$XA  ̗/… . <0… :|1ĉ+Z1ƃmܸ`|7n/ƍ۸qƍ7nܸqƍ۸qc|6nH1_|7˗oƍ7nܸqƍ7̗oƍqE O@ Da| H*\ȰÇ#JHŋ3j/ƍ ˷qF H*, <0… :|1ĉ+Z1c|4jԈ0_>5j,0 <0B H*\ȰÇ#JHŋ3b̗OFӨQF5jԨQF5jԨQc|4jԈ0_>5jԨQF5jԨQF5V̗OFӨQF5jԨQF5jԨQc|4jԈ0_>5jԨQF5jԨQF5V̗OFӨQF5jԨQF5jԨQc|4jx0߿|5jԨQF5jԨQF5j/F 70_>5jԨQF5jԨQF5N̗OF;/F5jԨQF5jԨQFEP| H*\P`'p "Lp!ÆB(q"Ŋ/b̨q#ǎ?6̗$H9$H A $H A/H 勘/H A $H A Rc| A*̗b| A $H A $H0_|@ $H A $H `| $H A $H +d|>$H A $H A/H90_> A $H A d|@|@ $H A $H 2_>  $H AH H/,h „ ˷p…O@ DPB >QD-^ĘQF=n̗c|>J̗Ǐ?~Ǐ?~1_}Ǐ?~Ǐ?~1_/_>/G}Ǐ?~Ǐ-0߿|'0_4c|?~Ǐ?~G9/@ 7? 4H0_8`A˗A'p "Lp!ÆB(q"Ŋ/b̨q#ǎ˗0_|W1|Q̗Ǐ?~Ǐ?~0_#|O7p 8p˗? 4xaB 6tbD)VxcF9v0_  'P__>$X | H*\ȰÇ#JHŋ3jȱG O@ DH_>$X`| '0| ̗/|$XA .dC%NXE5n#|'p "< $`>'0| w˗? 4xaB 6tbD)VxcF9vx0_  $XA .dC%NXE5n#|˗|>~l/_|?~Ǐ?~G%a|?&O@$XA .dC%NXE5n|>N̗/Ǐ(? 4xaB 6tbD)VxcF9v0_|Ǐ?~Ǐ?>̗|>z̗/_?~Ǐ?~c|>f̗F O@ DPB >QD-^ĘQF=J̗|}0@ H*\ȰÇ#JHŋ3jȱG}/GǏ?~Ǐ?~/G}0@ H*\ȰÇ#JHŋ3jȱNj}/_ (? 4xaB 6tbD)VxcF9v1_˗#B O@ DPB >QD-^ĘQF=n̗G}4/_|?~Ǐ?~ǎ}h0_(? 4xaB 6tbD)VxcF9v1_˗#|'p "Lp!ÆB(q"Ŋ/b̨q#ǎ?˗$ȃӘ/_| A $H A $ȉ0_$H A $H A/H 0@ H*\ȰÇ#JHŋ3jȱǏ a|'P ,h „ 2l!Ĉ'Rh"ƌ7r#|@t/_>$H A $H AԘ/HK/_| A $H A $H)1_  <0… :|1ĉ+Z1ƍ;z0_> '˗|'p "Lp!ÆB(q"Ŋ/b̨q#ǎ?>̗$Ȋ  <0… :|1ĉ+Z1ƍ;z1_> -˗$H A $H A R`| AZ̗$H A $H A r`| AZ̗$H A $H A r`| AZ̗`| ̗/H A $H A b| AZ̗`>'0H A $H A rb| AZ̗`>$H A $H A91_> -g0|$H A $H A91_> -g0|$H A H H QP| H*\a| 6lذaÆ8`A&D <0… :|1ĉ+Z1mܸ`|7n0@ HO@$XA .dC%NXE5˧QFiԨ1c|5˗/_>5jԨQF5j0_>5"̗OFӨQ`|iԨQF5jԨQFiԨa|5j/F˗OF5jԨQF5J̗O#F$XA .D <0ƒ.\pa|'p "Lp!ÆB(q"Ŋ/b̨`|!'p`>$XA .D0 H*̧PB ˗/,h „ 2l!Ĉ'Rh"ƌ˷a7̷Qc˗oƍ7nܸqƍ7"̗o|7nD/Ƌ6n/_7nܸqƍ7nܘ0_mܸa|-[`惘/_7nܸqƍ7nܨ0_mܸa|-[a ˷qƍ7nܸqƍ˷a7"̗oc| /_|O`|˗/|mܸqƍ7nܸqƅmtoƍX1|'0|˗/,/,h „ 2l!Ĉ'Rh"ƌ˷a7"̗o#| /|`>_>$X0_>$XA .dC%NXE52̗o|7nD/F+_>_|˗O`>۸qƍ7nܸqƍ 0F ;o|6R`>|/߿? ̗/,h „ 2l!Ĉ'Rh"ƌ˷a 5̷Qa|˗a˷qƍ7nܸqƍ˷a /_|o#|6&O@ <0'p "Lp!ÆB(q"Ŋ/b̨a|ۨ0_| '0_|˷1!| /$0@ H <0… :|1ĉ+Z1Ɔmto|'0|mD0 <0aO@ ̗` ,(0_>$XA .dC%NXE56̗o|+_>o#B$XA(07_/_'`>Gp O@ DPB >QD-^ĘQc|6:̷Q!|/߿_>$XA!D!|;aA /߿O@O`O@ DPB >QD-^ĘQ#|6:̷qFmL/_| '0| '0|O`> ˷qƍ7nܸqƍ˷a7"̗oc| '0_>'0|O`>+/ƍ7nܸqƍ7nd/F6n܈0_1g0| ̗/_>'p|/O@ DPB >QD-^ĘQ#|6:̷qFmoc0˷qƍ7nܸqƍ˷a7"̗o|˗Oc7nܸqƍ7nܸ0_mܸa|/۸Q`|7nܸqƍ7nܸQa|۸q#|6b̷q|7nܸqƍ7nܸ1a|۸q#|6f̷q|7nܸqƍ7nܸ1a|˷qFۨ1ƍmܸqƍ7nܸqFm|/_7 O@$XA ˧PB  <0… :|1ĉ+Z1Fm0 <0… 'p "L0_| *T`>$XA .dC%NXE5̗oD$XA .dX? 4xaB[p…'p "Lp!ÆB(q"Ŋ/bq`|7n,/ƍ/'P ,h „O@ DPB >QD-^ĘQ|6nX0_7bO@ DPaA$XA .dC%NXE3˧QFiԨQA$XA O@ DPB >QD-^Ęc|5jD/F5jԨQF5jԨQF+˧QFiԨQF5jԨQF5jԨb|5jD/F5jԨQF5jԨQF+˧QFiԨQF5jԨQF5jԨb|5jD/F5jԨQF5jԨQF+˧QFiԨQF5jԨQF5jԨb|5jD/F5jԨQF5jԨQF+˧QFiԨQF5jԨQF5jԨb|5jD|8`A&TaC!F8bE1fԸcG'|@ $H A $H !|,h „ 2, <0… :|1ĉ+Z1ƍ;zT/Džb|>~Ǐ?~Ǐ0_3Ǐ?~Ǐ?~4/G>~ܘ/Ǐ?~Ǐ?~`|qc|?~Ǐ?~ǂ}TǍ}Ǐ?~Ǐ Qa7Ǐ?~Ǐ?~,/G>~ܘ/Ǐ?~Ǐ?~`|qc|?~Ǐ?~ǂ}To#|'p ;xA'p "Lp!ÆB(q"Ŋ/b̨q#ǎ Qa8/_?~Ǐ?~c|>*̷1|/_/|/_|Ǐ?~Ǐ?̗|(߿__>$X`|8`A&TaC!F8bE1fԸcG0|0@'P`>0@ H'p "Lp!ÆB(q"Ŋ/b̨q#ǎ Qa ˗_|˗O`_|i̗Ǐ?~Ǐ?~X0_ mO@#'A$X`|8`A&TaC!F8bE1fԸcG0ǏǏ?~Ǐ?̗|?n̗Ǐ?~Ǐ?~X0_ }1_?~Ǐ?~c|>*|>~Ǐ?~Ǐ0ǏǏ?~Ǐ?̗|?n̗Ǐ?~Ǐ?~X0_ }1_?~Ǐ?~c|>*|>~Ǐ?~Ǐ0ǏǏ?裏>裏>*|8`A̗/a„ &L0a|'p "Lp!ÆB(q"Ŋ/b̨q#ǎ !|O@ DPB 8? 4xaB 6tbD)VxcF9vX0_ 8`A&TaB$XA .dC%NXE5n|>NO@ DP„ H*\ȰÇ#JHŋ3jȱdž}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_?~Ǐ?~lj}1_>$XA .dC%NXE5nljY1_|@ $H A $H |$H A $H A/HC$H A $H A1_> ![/H A $H A c| A:̗a| A $H A $ȍ0_> $H A $H 3|, $H A $H Ab̗$Ȅ2$H A $H A/H/H A $H@ $@|8`A&Tp`| "̗? 4xaB 6tbD)VxcF9vQ`| A̗$| A $H A $Ȉ)0ȃ $H A $H d| $H A $H Al/Ht/H A $H A ra| ;)1H A $H A Ra| '0_|1_> $H A $H A"̗a˗O`|q̗$|@ $H A $Hs_> o ,h`|$XA .dC%NXE5n#|80_>  /_|̗? 4xaB 6tbD)VxcF9v0_>> ̗b泘Ǐ?~Ǐ?~0_Yg`> o(0_>$XA .dC%NXE5n|>:̗"|߿| /߿_O@ ̗? 4xaB 6tbD)VxcF9v`> 4xaB HA O`/_$XA .dC%NXE5n#B$XA 'p 3O`> '0߿|QD-^ĘQF=~Ę/E߿|߿| _>$X |O@ DPB >QD-^ĘQF=~Ԙ/_> 'P ,h „ 2l!Ĉ'Rh"ƌ7rc|i`>8`A&TaC!F8bE1fԸcGA˗/d  <0… :|1ĉ+Z1ƍ;z`|!?˗/_Ȑ!C 2dȐ!C 2$|0@ H*\ȰÇ#JHŋ3jȱǏ ˗/E O@ DPB >QD-^ĘQF=~0_(? 4xaB 6tbD)VxcF9v|BF̗/_!C 2dȐ!C 2dH `>8`A&TaC!F8bE1fԸcGAf̗/_Ȅ  <0… :|1ĉ+Z1ƍ;zc|!˗/_Ȑ!C 2dȐ!C 2d|B̗/_!C 2dȐ!C 2dȐ`>8`A&TaC!F8bE1fԸcGA4/_G O@ DPB >QD-^ĘQF=~Ra|˗OH"E)RH"E)c|,'P ,h „ 2l!Ĉ'Rh"ƌ7r#Ȑ'`>8`A&TaC!F8bE1fԸcGA/C O@ DPB >QD-^ĘQF=~c| ˗OH"E)RH"E)R|!O@$XA .dC%NXE5nG!=˗ |'p "Lp!ÆB(q"Ŋ/b̨q#ǎ? )2_  <0… :|1ĉ+Z1ƍ;z2H7rȑ#G9rȑ#G9`|F9rȑ#G9rȑ#G̗oȑ#G9rȑ#G9r$|F9rȑ#G9rȑ#G"̗`| ̗/ȑ#G9rȑ#G9r$| _|9rȑ#G9rȑ#Gn̗`>oȑ#G9rȑ#G9rc| /_>F9rȑ#G9rȑ#7g0|7rȑ#G9rȑ#G@ <0… :|1ĉ+Z1ƍ;z2ȁ ? 4xaB 6tbD)VxcF9vdH8? 4xaB 6tbD)VxcF9vdH˗oȑ#G9rȑ#G9r|9rȑ#G9rȑ#Gy0_#G9rȑ#G9rȑ9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rd|#G9rȑ#G9rȑ#'p࿁8`A&TaC!F8bE1fԸcGA/_|D)RH"E)RH"E&1H"E)RH"E)RHM̗OH"E)RH"E)R|)RH"E)RH"E/c>"E)RH"E)RȐ6)RH"E)RH"Ec>"E)RH"E)RH:)RH"E)RH"Ec>"E)RH"E)RH>'RH"E)RH"E1|Ob| H*\ȰÇ#JHŋ3jȱǏ C*W0|囘OH"E)RH"E)Rc> ˗_|˗/|D)RH"E)RH"3;/_|˗O`>g0_>"E)RH"E)RȌ/߿| 70|D)RH"E)RH"3+/|˗O`>g0_>"E)RH"E)RȌ 'P | /_>$XA .dC%NXE5nG!櫘Oa|"E)RH"E)RHU̗0_|"E)RH"E)RH}̗OH"E)RH"E)rc)RH"E)RH"Er1_|"E)RH"E)RHm̗/H"E)RH"E)R|)RH"E)RH"E/c|D)RH"E)RH"Cg1_|"E)RH"E)RH"71_|D)RH"E)RHDi O@(? 4xaB 6tbD)VxcF9vdȋ˗`>8`A&TaC!F8bE1fԸcGA0 O@ DPB >QD-^ĘQF=~#| <0… :|1ĉ+Z1ƍ;z2H8`A&TaC!F8bE1fԸcGA9dI'QTeK/aƔ9fM7qԹgO?:hQG&UiSOF:jUWfպkW_;lYgѦUm[oƕ;n]wջo_)O@$X |'p "Lp!ÆB(q"ŊY0|'K/_>gѢE-ZhѢE,Z|`>!̗"|YhѢE-Zhq`'0|˗o`|˗o`|K`>`|˗O`|w0_> hѢE-Zh|'0| ̗`>70| w0|#o`/|峸0_>-ZhѢE- w0|#`>G0_3`>߿|/_? #(0_>O`|˗o`|| H*\ȰÇ#JH|g0_[/|˗0|g0|G0|˗`|'0_| /_g0E-ZhѢEw0_|70_|c/_ /a>3` /_>w0_|G0|70|gѢE-ZhB$8?#(0_# A_>'p@7_(08p?'0_o`|O@ H*\ȰÇ#JHb|+O`>'0_ ̗/|K` '0_/_S`| /߿|O`˗/|,ZhѢE-Z_/_>˗/|;/_|(߿80| /_|˗/߿|/_|˗o/_`>7߿'p| H*\ȰÇ#JHb|->g0ʼn ga>-ZhѢE- g|Y`|gѢE-ZhѢE,Z|`>̗Ϣ|,ZhѢE-Z80Egqb>YD/_>-ZhѢE-g|Y/a|,̗/E-ZhѢE ha>,Ņ`>8`  <0… :|1ĉ+FO@ DPAO@ Dx? O@ O@ DPB >QD-^ĘQF=~RH%MDRJ-]SL5męSN=}TPEETRM>UTU^ŚUV]~;;PKPKFJOEBPS/img/lobapp.gif]GIF87aP?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,P H*\ȰÇ'p " <0… :|1ĉ+Z1ƍ;VO@$XA  <0… :|1ĉ+Z1ƍ;F̗/_> ѣG=zѣG=z̗#|=zѣG=zQc|`|=zѣG=zѣ|˗/߿|;/_>0 O| H*\ȰÇ#JHŋ3jȱ|/߿|g0_/߿|/_> ѣG=zѣG/˗/|70| ̗_>/|8`AO@ DPB >QD-^ĘQƋ#o`3O`/|O@  <`>$XA .dC%NXE5n`|_|'0__ W0G8rȑ#G9r#|,h `|˗_|O |_@'p "<? 4xaB 6tbD)VxcF]0_|6N̗o#|7nܸqƍ7nܸa;/_CO@ ̗? 4xaB 6tbD)VxcF]̷0|6>̗o|7nܸqƍ7nܸ`> O@ 7p@/_| H˗/a„  <0… :|1ĉ+Z1ƃG0| )O@$XA  <0| H*\ȰÇ#JHŋ3j<a|Coa> H'p "LX0,h „ 2l!Ĉ'Rh"ƌ `| ̇0|mܸqb7nܸqƍ7nX0߿|o`>3oƍmܸqƍ7nܸqF(߿| (`> O@ DPB 'p H*\ȰÇ#JHŋ3.̗/_|̗o`>+`>5Z0_|5jԨQF5jH1|G0|g0F-ӨQF5jԨQF-w1|5jb>5jԨQF5joaS08` H*O@,X_>$XA .dC%NXEcb˗`|˗/ƌ˗0|5jԨQF5j1|-̇0_>-̗OFC/b>5jԨQF5j|a;/|˧Q|拘OF5jԨQFcb> 0_iԈ0_>$ӨQF5jԨQƇ'p  'p A W| ̗` ,X` +H0_ ,80,h „ 2l!Ĉ'Rh"ƌi` O`|9̗1_| +Ob>5jԨQF5j|OƁ#_|'0_|/_| /_|_|˗/|g0|5jԨQF5j0ƌa+/߿|˗/|+/߿|˗_|/_|/_|/_|iԨQF5jԨQ|5 ̗!|O|/_ _O`_|(0_8p| H*\ȰÇ#JHŋ3 ̧Q|/_70߿|`˗/߿|O7p 8p <0… :|1ĉ+Z1|5w0|+O`|˗o` '0| ̗o`|/_>ˇ1F5jԨQF5>̧Q|w0_|˗/| ̗`> /߿_(0_8p| H*\ȰÇ#JHŋ3 ̧Q|w0_>˗1F5jԨQF5>̧Q#|˗0_   <0… :|1ĉ+Z0 <0B H_ ,X` ˗/_+H0_| ,X` /_ ,/_8`A 'p |,h „8?O@'p A HP |,h 0 H@$H? 4/;H0_| 'p (? #H A$`> 'p A (? ,ϠA 4h`| 3hРA 4X`>'p H* < |<(0|$XA .dC[O"|I0|ˇ0_>w0A7?#80_>G`|#Hp`| $/ _7P80_|7_8p| H*\ȰÇ#:̷0|G0_| 3a|˗O`| O/߿80 8p`|˗o/ (0| / 8p`|˗o@7_|8P`80| o` ̗_8p` <0… :|1"| G0| ̗`>70| /|O`|w0_| g0_|/_CO` 3/|g0_|˗_|0߿|/|G0| /a 'QD%J(`>;o`/_| ̇0_| /|̗O`+o`>#_| ̗_|˗`| ̇0|70|_| /߿| ̗_8p /o|̗/|o70,h „ 2l!Ĉw0_+O`> #_'0| /|/|̗/|W0_>C/|!'0_|/|˗`#`|8@0@߿8 |'P`>0 <0… :|1ĉ8_'`>(`>'p|/_|˗O |__> O@ H | O/߿| 'p@O`>08 A@/_| 0@ H_|+(0߿|G0_'0_AO@ DPB >Q|`>+`'P| o|/߿| o| 8p|˗o|/_ /8P`7p`7p/_|'0_(0__80| o` /| 7p|'p "Lp!ÆB(a#o`| W0|̗o` +`>'0_`>/| '0_|O`>˗/| w0|˗`|˗/|70|(7P࿁(0_|'P'p`>$XA .dC%N`| ̗/_g0|/_|(߿|o`>7p`/ 8p8_8p|7p /8_|8_>$XA ̷p… .\p… .\` 3o… 3/̗oa|[P`>-/|&̗o| .\` .\p… .\p…-\0| .\H0|ˇ0_w0…̗oa|[0_-\pB.\p… .\p… ̷p!|-\p!|S/_|̗a ;/|˗o|̷p… [p… .\p… .\H0,h|!D!B˗`|̗/BC/B!̗/|!/_>ˇ|"D!8`A&TaC!F8_> G"| 8 0@ (`>8`> $H0A8 $0@ `>8` H*4 <0… :|1ĉ8`A 'p |,h „8?O@'p A HP |,h 0 H@$H? 4xaB 6tbD)VxcF9vdH#I4yeJ+YtfL3iִygN;yhPC5ziRK6ujTSVzkV[vlXcɖ5{mZkٶun\sֵ{o^{p` 6|qbŋ7vXp@;;PK$x%̧PKFJOEBPS/img/alldesc.gif*;GIF87aX?**?***UU?UUU????**?*******?*******U*U?*U*U*U**?*****?*****?*****?***UU?UUUU*U*?U*U*U*UUUU?UUUUUUUU?UUUUU?UUUUU?UUUUU?UUU?**?***UU?UUU?????**?***UU?UUU?????**?***UU?UUU?ժժ?ժժժ???**?***UU?UUU?????***UUU,X H*\ȰÇ#JHŋ3jȱǏ CIɓ('p O@ DPB >QD''p "LH? 4xaB 6tbD)V0_| ˗ŋ/^xʼn.^ŋ/^xŋw`|.^xŋ/^.^xŋ/^0_ xŋ/^x1bxŋ/^xb| h0_/^xŋ!C/_|̗/|#/|]xŋ/^xa| Y̗ŋ/^xE/߿| '0|70|/^xŋ/^d/|`>70߿ ߿| H*\ȰÇ#JH|#_ O`|'0|-ZhѢE-Z/_>/߿| /_'0߿|gѢE-ZhŁ ;o`o`| w0E-ZhѢE-w0߿|˗/| ̗/|̗ϢE-ZhѢE70_| W0? O|O8`A&TaC!F8bE ˗`0o(`> 4xaA$XA .dC%Nl/_|/|70@ ?˗/,h „ 2l!Ĉ'Rh`O`_|'0߿|1ŋ/^x"|;o`|70_/|70ŋ/^xŋ#/| `>70߿O| H O@ DPB >QD ;0o`/߿70߿߿| H*\ȰÇ#J8`> 4x `| ,H0_+X` /,h „ 2l!Ĉ'W0E̗"E)RH"E(.0|&˗/|(R"E)RH"|Qx0_|)RH"E)"GqaGa|)G"E)RHb>(R<`>)RH"E棸0|Gqa|)G"E)RHb>(R<`>)RH"E;0@ @ o 80_| H;xO@ DPB >QD H`(RH"E)RD`o`>[0 <8? 4xa*TPB *TPB *Th0A$XA 'P`>$XA .dC%N`> o`|-G1b>H"E)R1EQH"E)Rh0߿|W0߿|70|)R0E)RH"EHb>)RH"Ew0_|+|'p` ? 4xaB *װaÆ 6lذaÆ g0_Æ "װaÆ 6lذaÆ 6,08_>/|'p H*\P!|, <0… :|1C$X? 4xaB8`A$XA .dC%6̗`|70_3`>&N8a>M8qĉ'6w0|'Na|'N8qĉC_ ˗/|+o`&N8a>&N8qĉ;`'1ĉ'N8qĄ0| ˗o?$XA8| ? 4xaB 6tbĄ 30 < `'p "Lp!ÆB(a&2̷0B 'P ,hA O@$H_>$XA .dC惘`> c/b>%J(QD-'a˗`|˗ODˇ0_|%J(QDEg0D11D%J(QD0|ˇ0_| 'Qb|1D%J(Q"|'Q"| E'QD%J(b$60|˗0_>-̗`$J(QD!拘` ˗`|70| E'QD%J(b$60_|w0| H̗`>)TPB *TPB S0_|70| ̗o` ̧`> *TPB *TPB)0 W0_|(߿?8p'p "Lp!ÆBx0|70_|/_>[/_|%J(QD!(Q|9G0߿| /߿|/߿|/_|o` 70_|I(QD%B'_>`|O`擘OD%J(Q"|%J$o`>̗/|`|W0_>/|/$J(QD!/_`|O`'_>%J(QDO@ DP!|[8`>'p`|'0|_˗_ O   <0… :|1|˗/|̗`> /O@ H| H*\ȰÇ#J_