COBOL tips for performance improvements

  • Always consider using SEARCH ALL option instead of checking long table by coding.
  • Internal SORT is usually uses longer CPU than External SORT.
  • Always consider using Evaluate, it creates program more modular.
  • Avoid using go to statement as they create irregular flow.
  • Initializing field is more efficient as follows:

INITIALIZE WS-CHARC with SPACES
INITIALIZE WS-NUMERIC with ZEROS
  • Unnecessary computations should be eliminated.

Efficient Code

INITIALIZE FIN-TOTAL
PERFORM VARYING I FROM 1 BY 1 UNTIL I = 40
COMPUTE FIN-TOTAL = FIN-TOTAL + ITEM(I)
END-PERFORM
COMPUTE FIN-TOTAL = FIN-TOTAL * PERCENT DIS

Inefficient Code

INITIALIZE FIN-TOTAL
PERFORM VARYING I FROM 1 BY 1 UNTIL I = 40
COMPUTE FIN-TOTAL = FIN-TOTAL + ITEM (I) * PERCENT DIS
END-PERFORM

  • When using PERFORM VARYING clause, using COMP data types is efficient than USAGE DISPLAY for the loop control variables.
  • Check boundary always for any arrays. If you expect 100 occurs then always have that check, this helps to know if arrays limit is reached.
  • If you need any specific data from file, always load the array with that field instead of complete data from file.

How DB2 locks works?

DB2 Database Manager implicitly acquires locks as they are need, except for occasions where the Uncommitted Read isolation level is used.
It is possible for the DB2 Database Manager to acquire row-level locks or table-level locks on a specific table resource by executing a special form of the ALTER TABLE SQL statement. By default, the DB2 Database Manager always attempts to acquire row-level locks.
  
 The syntax is ALTER TABLE [Table NameLOCKSIZE [ROW | TABLE] 
 E.g. ALTER TABLE school LOCKSIZE TABLE
The DB2 Database Manager will attempt to acquire table-level locks for every transaction that accesses the SCHOOL table.
The syntax for the LOCK TABLE statement is:
LOCK TABLE [Table Name] IN [SHARE | EXCLUSIVE] MODE
The LOCK TABLE statement allows a transaction to acquire a table-level lock on a particular table in one of two modes: SHARE mode and EXCLUSIVE mode.
If a table is locked using the SHARE mode, a table-level Share (S) lock is acquired on behalf of the requesting transaction, and other concurrent transactions are allowed to read, but not change, data stored in the locked table.
On the other hand, if a table is locked using the EXCLUSIVE mode, a table-level Exclusive (X) lock is acquired, and other concurrent transactions can neither access nor modify data stored in the locked table. You can find the corresponding jobs/JCLs here.

Selecting required lock

The DB2 Database Manager implicitly makes decision of which lock to be used by analyzing the transaction to determine what type of processing it has been designed to perform.

To decide on which type of lock is needed for particular DB2 query, the DB2 Database Manager places all transactions into one of the following categories:

  •   Read-Only
  •   Intent-to-Change
  •   Change
  •   Cursor-Controlled

COBOL DATE FUNCTION

There was requirement were we had to send MT202 to Swift. Swift accepts time of GMT or either it accepts with correct offset and when we use current time option in COBOL it gives local time hence we were getting ET time.I had faced issue with time. The offset I was getting was not correct from GMT. 

For E.g.: ET time is 4 hrs offset from GMT when day-light saving is on and it is 5 hrs offset from GMT when day light saving is off.  

I used following function and by using this function we get the offset from GMT of where your application is running, then we can easily just use native COBOL.


See the CURRENT-DATE intrinsic function at:

http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IGY3LR31/7.1.15

Positions 17-21 will give you the exact offset from GMT.

Unless your application is running in one of the time zones with 15 or 30 minute offsets from GMT, then “converting” from/to GMT becomes trivial without resorting to an LE call-able service (much less a C or Assembler subroutine).

Character 17 is sign value ‘-‘or ‘+’. This sign is ‘-‘ if GMT is ahead of local time and ‘+’ if the GMT is behind of local time.  

Create files with matching and non-matching records

There are two input files containing lists of records, as follows:

Input File1

V
F
C
H
D

Input File2

K
H
C
V
M

How can we create output files for the following?

  • The records that appear in both File1 and File2
  • The records that appear only in File1
  • The records that appear only in File2

Below is an ICETOOL job that can do this match by using the SPLICE operator. SPLICE operator in ICETOOL helps to perform various file join and match operations. 


This can be done by adding an identifier of ’11’ to the File1 records, add an identifier of ’33’ to the File2 records, and splice the second id byte for matching records so we get ’13’ for records in both files, ’11’ for records only in File1 and ’33’ for records only in File2.


//S1 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN1 DD DSN=… input File1
//IN2 DD DSN=… input File2
//T1 DD DSN=&&T1,UNIT=SYSDA,SPACE=(TRK,(5,5))
//* USE MOD FOR T1
// DISP=(MOD,PASS)
//OUT13 DD SYSOUT=* records in File1 and File2
//OUT1 DD SYSOUT=* records in File1 only
//OUT3 DD SYSOUT=* records in File2 only
//TOOLIN DD *
* Add ’11’ identifier for FILE1 records.
COPY FROM(IN1) TO(T1) USING(CTL1)
*Add ’22’ identifier for FILE2 records.
COPY FROM(IN2) TO(T1) USING(CTL2)
* SPLICE to match up records and write them to their appropriate output files.
SPLICE FROM(T1) TO(OUT12) ON(1,1*,CH) WITH(13,1) –
USING(CTL3) KEEPNODUPS
/*
//CTL1CNTL DD *
* Mark FILE1 records with ’11’
INREC OVERLAY=(12:C’11’)
/*
//CTL2CNTL DD *
* Mark FILE2 records with ’33’
INREC OVERLAY=(12:C’33’)
/*
//CTL3CNTL DD *
**** Write matching records to OUT13 file and removes id.
OUTFIL FNAMES=OUT13,INCLUDE=(12,2,CH,EQ,C’13’),BUILD=(1,1*)

**** Write FILE1 only records to OUT1 file and removes id.
OUTFIL FNAMES=OUT1,INCLUDE=(12,2,CH,EQ,C’11’),BUILD=(1,1*)

**** Write FILE2 only records to OUT3 file and removes id.
OUTFIL FNAMES=OUT3,INCLUDE=(12,2,CH,EQ,C’33’),BUILD=(1,1*)
/*

The output files will have the following records:
OUT13
C
H
V

OUT1
F
D

OUT3
K
M

Add new DB2 program in Changeman

Point to take care while creating new DB2 program in changeman and to promote it to test regions

Create a PKG member in the package where a new DB2 program is present. This member is required in order for DBRM to be promoted to the test region. If this member is not present, changeman gives error while promoting DBRM.

          BIND PACKAGE      (PVNPRBDL) +
                MEMBER          (PVNBPBOT) + 
                OWNER            (DABOC) + 
                QUALIFIER       (PVNDB001) + 
                ACTION           (REPLACE) + 
                DEGREE          (1) +  
                ISOLATION      (CS) + 
                VALIDATE       (BIND) + 
                EXPLAIN         (YES) +  
                 RELEASE       (COMMIT) + 
                CURRENTDATA  (YES) 


Member name = New program name.

Whenever we promote a DB2 component we need to promote all the three components related to the program namely DBR, LDB,PKG. Bind will automatically occur.
So we do not require a separate JCL to bind.

                PVNPNOT           DBR
                PVNPNOT           LDB
                PVNPNOT           PKG

In some mainframe enviornments, do not bind a program to a plan, since in the environment a lot of packages are bound to a plan. Doing a plan bind results in corruption of plan as only one DBRM is bound to the specific plan then.

So always do a package bind by the above process in case plan is bound by various packages in the test region. (Please check environment details with DBA before binding any program).

What is OTE (Open Transaction Environment)?

Task Control Block 

The open transaction environment (OTE) function was added to CICS Transaction Server for OS/390, Version 1 Release 3 and later versions.

In earlier releases of CICS, CICS ran all user transactions under a single z/OS TCB, the CICS quasi-reentrant (QR) TCB. Direct invocation of other services outside the scope of the CICS permitted interfaces could interfere with the use by CICS of the QR TCB. In particular, requests that resulted in the suspension (“blocking”) of the QR TCB, which happens when an MVS wait is issued, would cause all CICS tasks to wait. For example, some services provided by DB2, MVS, UNIX® System Services, or TCP/IP, might result in TCB blocking.



Open Transaction Enviornment

The open transaction environment is an environment where CICS application code can use non-CICS services (facilities outside the scope of the CICS API) within the CICS address space, without interference with other transactions. Applications that exploit the open transaction environment run on their own open TCB, rather than on the QR TCB. Unlike the QR TCB, CICS does not perform sub-dispatching on an open TCB. If the application running on an open TCB invokes a non-CICS service that blocks the TCB, the TCB blocking does not affect other CICS tasks.
MQGET OPTIONS to read Queue in Non Destructive Way


To delete from queue explicitly, developer needs to Read a queue, performing some other action and finally delete queue explicitly.

Steps:
During MQOPEN Call:
  •  Open Queue with MQOO_BROWSE option
  •   Check the message counter

During MQGET Call:
  • For the first message give MQGMO_BROWSE_FIRST as GMO option
  • Do again MQGET after you perform everything you need with MQGMO_MSG_UNDER_CURSOR option. This will delete message from queue. By this we ensure that all the business logic is done before we delete message from queue.
  • For next subequent messages give MQGMO_BROWSE_NEXT and again do step 2 to ensure delete.
Eg:

IF Message-Counter = 0 

       COMPUTE MQGMO-OPTIONS = MQGMO_NO_WAIT +

                               MQGMO_BROWSE_FIRST + MQGMO_CONVERT

       END-COMPUTE
ELSE
       COMPUTE MQGMO-OPTIONS = MQGMO_NO_WAIT +
      MQGMO_BROWSE_NEXT  + MQGMO_CONVERT
       END-COMPUTE     
END-IF  


Call this para after every browse:


COMPUTE MQGMO-OPTIONS = MQGMO-NO-WAIT + MQGMO-MSG-UNDER-CURSOR

END-COMPUTE


DB2 Bind precompiler process

DB2 Bind Process  

Find a quick overview of the bind process in my earlier post.

                                         Process for Bind in Brief

PrecompilerFunctions:

Checks the DB2 code  in the program for errors. 
Adds working storage areas and source code compatible statements that are used to     invoke DB2. One to the working storage areas contains a literal “timestamp” called a consistency token.
Extracts all the SQL statement from the program source and placed into a member called   the DataBase Request Module, or DBRM, which has same consistency token.

Compiler:The COBOL code with SQL is input to complier and compiler checks for any error and Object Module is formed. This code is complied version of code.

Modified Code: 
The Object Module is input to Link-edit and modified code is linked to all the DB2 runtime components to create Load module or .exe file which is include in DB2COBOLprograms.
The 'timestamp' or consistency token is embed in this module which was generated in prec-ompiler stage. If there are more than one DB2 modules linked statically to load module then token  of each is generated and linked.

DB2 Bind:

  • Bind Process read DBRM which is created in precomplier stage and creates access path to read data.
  • Access path along with consistency token is stored in DB2 catalog tables as a package.
  • Every package is bound into package list or collection
  • Collection name is specified by package parameter.
  • A Collection is a group of Packages that are included in one or more Plans. The QUALIFIER parameter of the bind is used to direct the SQL to the specific set of DB2 objects (tables, views, aliases or synonyms) qualified by this name.
  • Apart from building plans and packages, bind also validates:
  1. SQL statements using DB2 Catalog
  2. Validates authorization id that if owner is allowed to perform bind process 
  3.  Selects access path depending upon availability of  indexes, table size etc. 

DB2-COBOL Program:

DB2 sub-system and plan name is given in JCL under SYSTSIN. 
When SQL statement is executed, DB2 searches for collection with the plan by package name and timestamp. This should match else it give bind error -805.

I have written DB2 bind as required in SCLM. The steps may vary for some other tools but the bind process remains same. 


The bind process

 The bind process establishes a relationship between an application program and its relational data. This step is necessary before you can execute your program. Currently, DB2 allows you two basic ways of binding a program: to a package, or directly to an application plan.

Even when they are bound into packages, all programs must be designated in an application plan. BIND PLAN establishes the relationship between DB2 and all DBRMs or packages in that plan. Plans can specify explicitly named DBRMs, packages, collections of packages, or a combination of these elements. The plan contains information about the designated DBRMs or packages and about the data the application program intends to use. It is stored in the DB2 catalog.


I am giving you one practical example to differentiate between plan and package and DBRM which i read recently in a book–

PLAN package and DBRM:-
Consider a grocery store analogy. Before going to a grocery store you prepare a shopping list. As you go through the list and you find an item in the list, you place the item in  your shopping cart. After you pay for the items at the check-out counter, the counter person  places item in your bag. You can think the purchasing item as DBRMs. The bag is the plan. You have multiple DBRMs(grocery items) in your plan(shopping bag).

In the package environment, rather than actually removing items from the shelf, you would mark on your shopping list the location of each item in the store. Later you gave the checked list to the counter person at the counter. The counter person then would place the list in the bag not the actual items. The Plan(bag) contains a list pointing to the physical location of the packages (grocery items) that are still on the self.

In addition to building packages and plans, the bind process:
Validates the SQL statements using the DB2 catalog.  During the bind process, DB2 checks your SQL statements for valid table, view, and column names. Because the bind process occurs as a separate step before program execution, errors are detected and can be corrected before the program is executed.
Verifies that the process binding the program is authorized to perform the data accessing operations requested by your program’s SQL statements. When you issue BIND, you can specify an authorization ID as the owner of the plan or package. The owner can be any one of the authorization IDs of the process performing the bind. The bind process determines whether the owner of the plan or package is authorized to access the data the program requests.Selects the access paths needed to access the DB2 data your program wants to process.In selecting an access path, DB2 considers indexes, table sizes, and other factors. DB2 considers all indexes available to access the data and decides which ones (if any) to use when selecting a path to the data.

Advantages of packages


Ease of maintenance: When you use packages, you do not need to bind the entire plan again when you change one SQL statement. You need to bind only the package associated 
with the changed SQL statement.

Incremental development of your program: Binding packages into package collections allows you to add packages to an existing application plan without having to bind the entire plan again. A collection is a group of associated packages. If you include a collection name in the package list when you bind a plan, any package in the collection becomes available to the plan. The collection can even be empty when you first bind the plan. Later, you can add packages to the collection, and drop or replace existing packages, without binding the plan again.

   

                         JCLS TO ALTER LOCK PARAMETERS OF ANY TABLE (DB2 V 9)

LOCKPART

JCL to alter tablespace lockpart parameter (only for partitioned) to NO in DB2

//PRODDB2  EXEC PGM=IKJEFT01,DYNAMNBR=30                

//STEPLIB  DD DSN=SYS1.DSN900.SDSNLOAD,DISP=SHR         
//SYSTSPRT DD SYSOUT=X                                  
//SYSTSIN  DD *                                         
    DSN SYSTEM(DB2PROD)                                    
          RUN PROGRAM(DSNTEP) PLAN(DB2PLAN) –         
          LIBRARY(‘DSN.DB2PROD.RUNLIB.LOAD’)            
      END                                               
//SYSPRINT DD SYSOUT=*                                  
//SYSUDUMP DD SYSOUT=*                                  
//SYSIN    DD *                                         
ALTER TABLESPACE PRDX1.TSSMG                            
LOCKPART NO;                                            
COMMIT;                                                 

This will give problem as tablespace is not stopped. it will give following error:

PAGE    1                                                                      
***INPUT STATEMENT:                                                             
 ALTER TABLESPACE PRDX1.TSSMG                                                   
 LOCKPART NO;                                                                  
SQLERROR ON   ALTER     COMMAND, EXECUTE   FUNCTION                            
 RESULT OF SQL STATEMENT:                                                      
 DSNT408I SQLCODE = -626, ERROR:  THE ALTER STATEMENT IS NOT EXECUTABLE BECAUSE  THE PAGE SET IS NOT STOPPED 
 DSNT418I SQLSTATE   = 55015 SQLSTATE RETURN CODE                               
 DSNT415I SQLERRP    = DSNXIATS SQL PROCEDURE DETECTING ERROR                  
 DSNT416I SQLERRD    = 155  0  0  -1  0  0 SQL DIAGNOSTIC INFORMATION          
 DSNT416I SQLERRD    = X’0000009B’  X’00000000′  X’00000000′  X’FFFFFFFF’  X’000
          INFORMATION                                                          
PAGE    1                                                                      
***INPUT STATEMENT:                                                            
 COMMIT;                                                                        
 RESULT OF SQL STATEMENT:                                                      
 DSNT400I SQLCODE = 000,  SUCCESSFUL EXECUTION                                 
 DSNT418I SQLSTATE   = 00000 SQLSTATE RETURN CODE                              
 DSNT416I SQLERRD    = 0  0  0  -1  0  0 SQL DIAGNOSTIC INFORMATION            
 DSNT416I SQLERRD    = X’00000000′  X’00000000′  X’00000000′  X’FFFFFFFF’  X’000


An ALTER statement specifies an ADD PART, BUFFERPOOL, USING, PRIQTY, SECQTY, ERASE, or GBPCACHE clause, but the page set is not stopped.

PAGE SET

PAGE SET is a physical grouping of pages. Page sets are of two types: 
Linear : DB2 uses linear page sets for simple table spaces, segmented table spaces, and indexes. 
Partitioned : DB2 uses partitioned page sets when it implements partitioned table spaces.
Each of the Page set is composed of several types of pages: header page, space map pages, dictionary pages, and data pages.

Here the page set is partitioned which is on table space.


Always check for tablespace status:

tso dsn s(Db2prod)    

-stop db(prdx1) sp(tssmg)

confirm using below command

-dis db(prdx1) sp(tssmg)

DSNT361I  -P *  DISPLAY DATABASE SUMMARY                                 
             *    GLOBAL                                                  
DSNT360I  -P ***********************************                         
DSNT362I  -P     DATABASE = PRDX1  STATUS = RW                           
                DBD LENGTH = 1434054                                      
DSNT397I  -P                                                             
NAME     TYPE PART  STATUS            PHYERRLO PHYERRHI CATALOG  PIECE   
——– —- —– —————– ——– ——– ——– —–   
TSSMG    TS    0001 STOP                                                 
    -THRU      0039                                                      
******* DISPLAY OF DATABASE PRDX1    ENDED      **********************   
DSN9022I  -P DSNTDDIS ‘DISPLAY DATABASE’ NORMAL COMPLETION               

DSN  


After this resubmit above job and it will be executed successfully.

PAGE    1                                                                      

***INPUT STATEMENT:                                                             

 ALTER TABLESPACE PRDX1.TSSMG                                                   
 LOCKPART NO;                                                                  
 RESULT OF SQL STATEMENT:                                                       
 DSNT400I SQLCODE = 000,  SUCCESSFUL EXECUTION                                 
 DSNT418I SQLSTATE   = 00000 SQLSTATE RETURN CODE                              
 DSNT416I SQLERRD    = 0  0  0  -1  0  0 SQL DIAGNOSTIC INFORMATION            
 DSNT416I SQLERRD    = X’00000000′  X’00000000′  X’00000000′  X’FFFFFFFF’  X’000
          INFORMATION                                                          
ALTER     SUCCESSFUL                                                            
PAGE    1                                                                      
***INPUT STATEMENT:                                                            
 COMMIT;                                                                        
 RESULT OF SQL STATEMENT:                                                      
 DSNT400I SQLCODE = 000,  SUCCESSFUL EXECUTION                                 
 DSNT418I SQLSTATE   = 00000 SQLSTATE RETURN CODE                              
 DSNT416I SQLERRD    = 0  0  0  -1  0  0 SQL DIAGNOSTIC INFORMATION            
 DSNT416I SQLERRD    = X’00000000′  X’00000000′  X’00000000′  X’FFFFFFFF’  X’000


LOCKSIZE

Alter tablespace to specify locksize tablespace using below job and it runs successfully.

//PRODSPU  EXEC PGM=IKJEFT01,DYNAMNBR=30                         
//STEPLIB  DD DSN=SYS1.DSN900.SDSNLOAD,DISP=SHR                  
//SYSTSPRT DD SYSOUT=X                                           
//SYSTSIN  DD *                                                  
    DSN SYSTEM(DB2PROD)                                             
          RUN PROGRAM(DSNTEP) PLAN(DB2PLAN) –                  
          LIBRARY(‘DSN900.DB2PROD.RUNLIB.LOAD’)                     
      END                                                        
//SYSPRINT DD SYSOUT=*                                           
//SYSUDUMP DD SYSOUT=*                                           
//SYSIN    DD *                                                  
ALTER TABLESPACE PRDX1.TSSMG                                     
LOCKSIZE TABLESPACE;                                             
COMMIT;                

start db(prdx1) sp(tssmg)    
                            
 DSN9022I  -P DSNTDDIS ‘START DATABASE’ NORMAL COMPLETION  
 DSN                                                                                                                                                                        


***                                                                         

-dis db(prdx1) sp(tssmg) 
                                                  
DSNT360I  -P ***********************************                           
DSNT361I  -P *  DISPLAY DATABASE SUMMARY                                    
             *    GLOBAL                                                   
DSNT360I  -P ***********************************                           
DSNT362I  -P     DATABASE = PRDX1  STATUS = RW                             
                DBD LENGTH = 1434054                                       
DSNT397I  -P                                                               
NAME     TYPE PART  STATUS            PHYERRLO PHYERRHI CATALOG  PIECE     
——– —- —– —————– ——– ——– ——– —–     
TSSMG    TS    0001 RW                                                     
    -THRU      0039                                                        
******* DISPLAY OF DATABASE PRDX1    ENDED      **********************     
DSN9022I  -P DSNTDDIS ‘DISPLAY DATABASE’ NORMAL COMPLETION                 
DSN                                                                        


This means to change locksize parameter, no need to stop tablespace but to change lock part parameter, stop tablespace.

Confirm lock size change from DB2 Catalog, and also status (A=> available)
SELECT                            
NAME                              
,DBNAME                           
,BPOOL                            
,PARTITIONS                       
,LOCKRULE    
,LOCKMAX                    
 FROM SYSIBM.SYSTABLESPACE         
WHERE NAME = ‘TSSMG’              
AND DBNAME = ‘PRDX1’              
WITH UR;                           
                 
Note: when you change locksize to tablespace(or table), lockmax automatically changes to 0             
NAME    DBNAME     BPOOL     PARTITIONS  LOCKRULE   LOCKMAX  STATUS 
——  ———         ——–       ———-          ——–  ——–        —— 
TSSMG   PRDX1        BP32K             39                   S             0            A      
Now, if when we try to alter tablespace lockmax parameter with value other than 0
, it shows error (because current locksize is tablespace/ table)
However, if the current locksize was ROW/ANY/PAGE, there would have been no DB2 error. 

//PRODSPU  EXEC PGM=IKJEFT01,DYNAMNBR=30                
//STEPLIB  DD DSN=SYS1.DSN900.SDSNLOAD,DISP=SHR         
//SYSTSPRT DD SYSOUT=X                                  
//SYSTSIN  DD *                                         
    DSN SYSTEM(DB2PROD)                                    
          RUN PROGRAM(DSNTEP) PLAN(DB2PLAN) –         
          LIBRARY(‘DSN900.DB2P.RUNLIB.LOAD’)            
      END                                               
//SYSPRINT DD SYSOUT=*                                  
//SYSUDUMP DD SYSOUT=*                                  
//SYSIN    DD *                                         
ALTER TABLESPACE PRDX1.TSSMG                            
LOCKMAX 1000;                                           
COMMIT

PAGE    1                                                                       

***INPUT STATEMENT:                                                            

 ALTER TABLESPACE PRDX1.TSSMG                                                  
 LOCKMAX 1000;                                                                  
SQLERROR ON   ALTER     COMMAND, EXECUTE   FUNCTION                            
 RESULT OF SQL STATEMENT:                                                      
 DSNT408I SQLCODE = -611, ERROR:  ONLY LOCKMAX 0 CAN BE SPECIFIED WHEN THE LOCK
 WHEN THE LOCK SIZE OF THE TABLESPACE IS TABLESPACE OR TABLE
 DSNT418I SQLSTATE   = 53088 SQLSTATE RETURN CODE                              
 DSNT415I SQLERRP    = DSNXIATS SQL PROCEDURE DETECTING ERROR                  
 DSNT416I SQLERRD    = 140  0  0  -1  0  0 SQL DIAGNOSTIC INFORMATION          
 DSNT416I SQLERRD    = X’0000008C’  X’00000000′  X’00000000′  X’FFFFFFFF’  X’000
          INFORMATION                                                          
PAGE    1                                                                          


This error is because lock escalation is not supported from tablespace or table levels.

Design a site like this with WordPress.com
Get started