0% found this document useful (0 votes)
4 views9 pages

Important Mainframe Concepts

The document explains key concepts related to SQL Code -811 in DB2, which occurs when a query retrieves multiple rows while expecting only one. It covers techniques for limiting query results using 'FETCH FIRST ROW ONLY', handling multiple rows with cursors, and passing data from JCL to COBOL. Additionally, it discusses static and dynamic OCCURS in COBOL, including 1D and 2D arrays, and provides best practices for using loops and cursors in DB2.

Uploaded by

srb120397
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views9 pages

Important Mainframe Concepts

The document explains key concepts related to SQL Code -811 in DB2, which occurs when a query retrieves multiple rows while expecting only one. It covers techniques for limiting query results using 'FETCH FIRST ROW ONLY', handling multiple rows with cursors, and passing data from JCL to COBOL. Additionally, it discusses static and dynamic OCCURS in COBOL, including 1D and 2D arrays, and provides best practices for using loops and cursors in DB2.

Uploaded by

srb120397
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Important Mainframe Concepts –

SQL Code -811

SQL Code -811 occurs in DB2 when a query retrieves more than one row, but the context of
the query or the way it's written expects only one row.

Using FETCH FIRST ROW ONLY

FETCH FIRST ROW ONLY limits the number of rows returned by the query to just one. You can
use it when you are not concerned about which specific row to retrieve or after sorting to get a
specific row.

SELECT EMP_ID, NAME, SALARY


FROM EMPLOYEE
ORDER BY SALARY DESC
FETCH FIRST ROW ONLY;

Handle Multiple Rows in Code

 If multiple rows are valid, modify the program to handle them using a cursor.

EXEC SQL
DECLARE EMP_CURSOR CURSOR FOR
SELECT EMP_ID, NAME
FROM EMPLOYEE
WHERE DEPT = 'SALES'
END-EXEC.

EXEC SQL
OPEN EMP_CURSOR
END-EXEC.

PERFORM UNTIL SQLCODE <> 0


EXEC SQL
FETCH EMP_CURSOR INTO :EMP_ID, :NAME
END-EXEC
END-PERFORM.

EXEC SQL
CLOSE EMP_CURSOR
END-EXEC.
PASSING DATA FROM JCL TO COBOL USING PARM -
1. Set Up the JCL

In the JCL, use the PARM keyword in the EXEC statement to pass the parameter value to the
COBOL program.

//JOBNAME JOB (ACCOUNT),'DESCRIPTION'


//STEP01 EXEC PGM=COBOLPGM,PARM='INPUTDATA'

Here, 'INPUTDATA' is the parameter being passed to the COBOL program.

2. Define the LINKAGE SECTION in COBOL

In COBOL, the PARM value is accessed through the LINKAGE SECTION and the PROCEDURE
DIVISION USING clause.

IDENTIFICATION DIVISION.
PROGRAM-ID. COBOLPGM.

ENVIRONMENT DIVISION.
DATA DIVISION.
LINKAGE SECTION.
01 PARM-DATA.
05 PARM-LENGTH PIC S9(4) COMP. *> Length of the parameter
05 PARM-VALUE PIC X(100). *> Actual parameter value

PROCEDURE DIVISION USING PARM-DATA.


BEGIN.
IF PARM-LENGTH > 0
DISPLAY 'PARM VALUE: ' PARM-VALUE(1:PARM-LENGTH)
ELSE
DISPLAY 'NO PARM VALUE PROVIDED'
END-IF.
STOP RUN.

3. Details of the Code

1. LINKAGE SECTION:
o PARM-LENGTH: Holds the length of the parameter passed.
o PARM-VALUE: Holds the actual parameter value. Use a sufficient size to accommodate
the expected parameter length.

2. PROCEDURE DIVISION USING:


o Connects the LINKAGE SECTION variable to the runtime environment, enabling the
program to access the passed data.
3. Handling Truncation:
o Use PARM-VALUE(1:PARM-LENGTH) to handle only the relevant portion of the
parameter.

STATIC AND DYNAMIC OCCURS IN COBOL-


1. Static OCCURS

 Definition: The number of occurrences is fixed and determined at compile-time.


 Declaration: The size of the array is explicitly defined in the OCCURS clause.
 Access: The array is accessed directly using a subscript or index.
 Use Case: Suitable when the number of elements is known and consistent throughout the
program.

Declaration of Static OCCURS

WORKING-STORAGE SECTION.
01 STUDENT-NAMES.
05 STUDENT-NAME PIC X(20) OCCURS 5 TIMES.

Accessing Static OCCURS

PROCEDURE DIVISION.
MOVE 'ALICE' TO STUDENT-NAME(1).
MOVE 'BOB' TO STUDENT-NAME(2).
DISPLAY STUDENT-NAME(1).
DISPLAY STUDENT-NAME(2).

2. Dynamic OCCURS

 Definition: The number of occurrences is variable and determined at runtime using the
DEPENDING ON clause.
 Declaration: The array size is specified as a range (1 TO m) and depends on a control variable.
 Access: The control variable determines the valid range of indices at runtime.
 Use Case: Useful when the number of elements changes dynamically based on runtime
conditions.

Declaration of Dynamic OCCURS

WORKING-STORAGE SECTION.
01 STUDENT-NAMES.
05 NUM-STUDENTS PIC 9(2). *> Control variable
05 STUDENT-NAME PIC X(20) OCCURS 1 TO 10 TIMES
DEPENDING ON NUM-STUDENTS.
Accessing Dynamic OCCURS
PROCEDURE DIVISION.
MOVE 3 TO NUM-STUDENTS. *> Array has 3 elements
MOVE 'ALICE' TO STUDENT-NAME(1).
MOVE 'BOB' TO STUDENT-NAME(2).
MOVE 'CHARLIE' TO STUDENT-NAME(3).

PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > NUM-STUDENTS


DISPLAY STUDENT-NAME(IDX)
END-PERFORM.

Key Differences Between Static and Dynamic OCCURS


Aspect Static OCCURS Dynamic OCCURS

Size Fixed at compile-time Variable, determined at runtime

OCCURS 1 TO m TIMES DEPENDING ON


Declaration Explicit OCCURS m TIMES var

Control Variable Not required Requires a control variable

Fixed size, occupies defined


Memory Allocation Memory allocation depends on runtime size
memory

Flexibility Limited Highly flexible

1-D and 2-D OCCURS IN COBOL-

1D (One-Dimensional) OCCURS

Declaration

The OCCURS clause is used to define a one-dimensional array.

WORKING-STORAGE SECTION.
01 STUDENT-NAMES.
05 STUDENT-NAME PIC X(20) OCCURS 5 TIMES.

 STUDENT-NAME: The array contains 5 elements.


 Each element is 20 characters long.

Accessing Elements

You access individual elements of a 1D array using a subscript or index.

cobol
Copy code
PROCEDURE DIVISION.
MOVE 'ALICE' TO STUDENT-NAME(1).
MOVE 'BOB' TO STUDENT-NAME(2).
DISPLAY STUDENT-NAME(1).
DISPLAY STUDENT-NAME(2).

2D (Two-Dimensional) OCCURS

Declaration

To declare a two-dimensional array, nest one OCCURS clause inside another.

WORKING-STORAGE SECTION.
01 SALES-TABLE.
05 REGION OCCURS 3 TIMES.
10 MONTH OCCURS 12 TIMES PIC 9(5).

 REGION: Represents 3 regions.


 MONTH: Represents 12 months for each region.
 Each element is 5 digits long.

Accessing Elements

You access elements of a 2D array using two subscripts: one for the outer dimension (REGION)
and one for the inner dimension (MONTH).

PROCEDURE DIVISION.
MOVE 100 TO SALES-TABLE(1, 1). *> Region 1, Month 1
MOVE 200 TO SALES-TABLE(2, 6). *> Region 2, Month 6
MOVE 300 TO SALES-TABLE(3, 12). *> Region 3, Month 12

DISPLAY 'Region 1, Month 1: ' SALES-TABLE(1, 1).


DISPLAY 'Region 2, Month 6: ' SALES-TABLE(2, 6).
DISPLAY 'Region 3, Month 12: ' SALES-TABLE(3, 12).

Output:

Region 1, Month 1: 100


Region 2, Month 6: 200
Region 3, Month 12: 300

Key Differences: 1D vs 2D
Aspect 1D OCCURS 2D OCCURS

Structure Linear array Matrix or table with rows and columns

Declaration Single OCCURS clause Nested OCCURS clauses

Access Method One subscript Two subscripts

Use Case List of names, numbers, etc. Tabular data like sales, temperatures, etc.

Using Loops for Array Access

1D Array

You can iterate over a 1D array using a loop.

PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 5


MOVE 'NAME-' TO STUDENT-NAME(IDX)
STRING IDX DELIMITED BY SIZE INTO STUDENT-NAME(IDX)
DISPLAY STUDENT-NAME(IDX)
END-PERFORM.

2D Array

For 2D arrays, use nested loops to iterate over rows and columns.

PERFORM VARYING REGION-IDX FROM 1 BY 1 UNTIL REGION-IDX > 3


PERFORM VARYING MONTH-IDX FROM 1 BY 1 UNTIL MONTH-IDX > 12
MOVE REGION-IDX * 100 + MONTH-IDX TO SALES-TABLE(REGION-IDX, MONTH-
IDX)
DISPLAY 'Region: ' REGION-IDX ' Month: ' MONTH-IDX
' Value: ' SALES-TABLE(REGION-IDX, MONTH-IDX)
END-PERFORM
END-PERFORM.

Best Practices

 Use subscripting for simpler arrays.


 Use indexing (INDEXED BY) for performance in large arrays.
 Ensure subscripts stay within declared bounds to avoid errors.
 For 2D arrays, clearly define row and column purposes for readability.
CURSORS IN DB2 –

Step 1: Declare the Cursor

A cursor is defined to hold the result set of a SELECT statement.

Syntax:

DECLARE cursor_name [SCROLL] CURSOR FOR


SELECT column1, column2, ...
FROM table_name
WHERE condition;

 cursor_name: Name of the cursor.


 SCROLL: Optional; specifies that the cursor allows both forward and backward movement (used
for scrollable cursors).
 SELECT: The query that retrieves the data.

Example:

DECLARE employee_cursor CURSOR FOR


SELECT emp_id, emp_name, salary
FROM employee
WHERE dept_id = 'D01';

Step 2: Open the Cursor

Opening the cursor executes the SELECT query and positions it before the first row of the result
set.

Syntax:

OPEN cursor_name;

Example:

OPEN employee_cursor;

Step 3: Fetch Data from the Cursor

The FETCH statement retrieves one row at a time from the cursor. You can move the cursor using
specific fetch options.
Syntax:

FETCH [NEXT | PRIOR | FIRST | LAST | RELATIVE n]


FROM cursor_name INTO host_variable1, host_variable2, ...;

 NEXT: Fetches the next row (default for non-scrollable cursors).


 PRIOR: Fetches the previous row (requires SCROLL).
 FIRST: Fetches the first row (requires SCROLL).
 LAST: Fetches the last row (requires SCROLL).
 RELATIVE n: Fetches a row relative to the current position (+n for forward, -n for backward).

Example:

FETCH NEXT FROM employee_cursor INTO :emp_id, :emp_name, :salary;

Step 4: Process the Fetched Data

Use the data retrieved from the cursor in your application logic (e.g., display or calculations).

Example:

DISPLAY 'Employee ID: ' emp_id


DISPLAY 'Employee Name: ' emp_name
DISPLAY 'Salary: ' salary

Step 5: Close the Cursor

When the cursor is no longer needed, close it to release the associated resources.

Syntax:

CLOSE cursor_name;

Example:

CLOSE employee_cursor;

Complete Example in Embedded SQL (COBOL)


Here’s a program that declares, opens, fetches, and closes a cursor:

DECLARE employee_cursor CURSOR FOR


SELECT emp_id, emp_name, salary
FROM employee
WHERE dept_id = 'D01'
END-EXEC.

EXEC SQL
OPEN employee_cursor
END-EXEC.

PERFORM UNTIL SQLCODE NOT = 0


EXEC SQL
FETCH employee_cursor INTO :emp_id, :emp_name, :salary
END-EXEC

DISPLAY 'Employee ID: ' emp_id


DISPLAY 'Employee Name: ' emp_name
DISPLAY 'Salary: ' salary
END-PERFORM.

EXEC SQL
CLOSE employee_cursor
END-EXEC.

You might also like