External interfaces in COBOL enable communication with systems, services, and programs outside the COBOL application. This includes calling external programs, interfacing with databases, communicating with web services, using system services, and integrating with other programming languages. Understanding external interfaces is essential for building integrated applications, accessing modern services, and extending COBOL capabilities in mainframe and distributed environments.
External interfaces allow COBOL programs to interact with:
These interfaces extend COBOL's capabilities and enable integration with modern systems and services.
The CALL statement invokes external programs or subprograms:
12345CALL "program-name" [USING parameter-1 [parameter-2 ...]] [ON EXCEPTION imperative-statement] [NOT ON EXCEPTION imperative-statement] END-CALL.
Components:
12345678910111213141516171819202122232425262728WORKING-STORAGE SECTION. 01 CUSTOMER-AMOUNT PIC 9(8)V99 VALUE 1000.00. 01 TAX-RATE PIC V999 VALUE 0.08. 01 TAX-AMOUNT PIC 9(8)V99. 01 CALL-STATUS PIC X VALUE 'N'. 88 CALL-SUCCESS VALUE 'Y'. 88 CALL-FAILED VALUE 'N'. PROCEDURE DIVISION. MAIN-PARA. CALL "CALCULATE-TAX" USING CUSTOMER-AMOUNT TAX-RATE TAX-AMOUNT ON EXCEPTION DISPLAY "ERROR: Tax calculation program not found" MOVE 'N' TO CALL-STATUS NOT ON EXCEPTION DISPLAY "Tax calculated: " TAX-AMOUNT MOVE 'Y' TO CALL-STATUS END-CALL IF CALL-SUCCESS DISPLAY "Total amount: " CUSTOMER-AMOUNT + TAX-AMOUNT END-IF STOP RUN.
Parameters can be passed by reference (default) or by value:
1234567891011*> BY REFERENCE (default) - called program can modify CALL "PROCESS-DATA" USING BY REFERENCE INPUT-DATA BY REFERENCE OUTPUT-DATA END-CALL *> BY VALUE - passes a copy, original cannot be modified CALL "VALIDATE-INPUT" USING BY VALUE CUSTOMER-ID BY VALUE AMOUNT END-CALL
BY REFERENCE passes the memory address, allowing the called program to modify the original variable. BY VALUE passes a copy, protecting the original from modification.
1234567891011121314WORKING-STORAGE SECTION. 01 PROGRAM-NAME PIC X(30) VALUE 'TAX-CALCULATOR'. 01 PROGRAM-PARAM PIC X(20). PROCEDURE DIVISION. MAIN-PARA. *> Call program using variable name CALL PROGRAM-NAME USING PROGRAM-PARAM ON EXCEPTION DISPLAY "Program " PROGRAM-NAME " not found" END-CALL STOP RUN.
You can use a variable for the program name, allowing dynamic program selection at runtime.
COBOL can interface with databases using embedded SQL:
123EXEC SQL sql-statement END-EXEC.
SQL statements are embedded in COBOL code and preprocessed before compilation.
1234567891011121314151617181920212223242526272829303132WORKING-STORAGE SECTION. 01 WS-CUSTOMER-ID PIC 9(5). 01 WS-CUSTOMER-NAME PIC X(30). 01 WS-CUSTOMER-BALANCE PIC 9(8)V99. EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 SQL-CUSTOMER-ID PIC 9(5). 01 SQL-CUSTOMER-NAME PIC X(30). 01 SQL-BALANCE PIC 9(8)V99. EXEC SQL END DECLARE SECTION END-EXEC. PROCEDURE DIVISION. MAIN-PARA. MOVE 12345 TO SQL-CUSTOMER-ID EXEC SQL SELECT CUSTOMER_NAME, BALANCE INTO :SQL-CUSTOMER-NAME, :SQL-BALANCE FROM CUSTOMERS WHERE CUSTOMER_ID = :SQL-CUSTOMER-ID END-EXEC IF SQLCODE = 0 MOVE SQL-CUSTOMER-NAME TO WS-CUSTOMER-NAME MOVE SQL-BALANCE TO WS-CUSTOMER-BALANCE DISPLAY "Customer: " WS-CUSTOMER-NAME DISPLAY "Balance: " WS-CUSTOMER-BALANCE ELSE DISPLAY "SQL Error: " SQLCODE END-IF STOP RUN.
Key points:
123456789101112EXEC SQL INSERT INTO CUSTOMERS (CUSTOMER_ID, CUSTOMER_NAME, BALANCE) VALUES (:SQL-CUSTOMER-ID, :SQL-CUSTOMER-NAME, :SQL-BALANCE) END-EXEC IF SQLCODE = 0 DISPLAY "Customer inserted successfully" ELSE DISPLAY "Insert failed: " SQLCODE END-IF
1234567891011EXEC SQL UPDATE CUSTOMERS SET BALANCE = :SQL-BALANCE WHERE CUSTOMER_ID = :SQL-CUSTOMER-ID END-EXEC IF SQLCODE = 0 DISPLAY "Update successful" ELSE DISPLAY "Update failed: " SQLCODE END-IF
COBOL can interface with web services, though implementation varies by environment:
On mainframes, CICS provides web service support:
123456789101112131415*> CICS web service invocation (conceptual) EXEC CICS WEB OPEN HOST('api.example.com') PORTNUMBER(443) END-EXEC EXEC CICS WEB SEND GET PATH('/api/customers/12345') END-EXEC EXEC CICS WEB RECEIVE INTO(WS-RESPONSE-BUFFER) LENGTH(WS-RESPONSE-LENGTH) END-EXEC
CICS web services allow COBOL programs to act as both web service clients and servers.
Some COBOL implementations support HTTP directly:
12345678910111213*> HTTP GET request (conceptual, implementation varies) CALL "HTTP-GET" USING BY REFERENCE WS-URL BY REFERENCE WS-RESPONSE BY REFERENCE WS-STATUS-CODE END-CALL IF WS-STATUS-CODE = 200 *> Process successful response DISPLAY "Response: " WS-RESPONSE ELSE DISPLAY "HTTP Error: " WS-STATUS-CODE END-IF
COBOL can call system services and operating system functions:
1234567891011*> Call system command (conceptual) CALL "SYSTEM" USING BY REFERENCE WS-COMMAND BY REFERENCE WS-RETURN-CODE END-CALL IF WS-RETURN-CODE = 0 DISPLAY "Command executed successfully" ELSE DISPLAY "Command failed: " WS-RETURN-CODE END-IF
12345678910111213141516WORKING-STORAGE SECTION. 01 CURRENT-DATE PIC 9(8). 01 CURRENT-TIME PIC 9(8). PROCEDURE DIVISION. MAIN-PARA. *> Get system date ACCEPT CURRENT-DATE FROM DATE YYYYMMDD *> Get system time ACCEPT CURRENT-TIME FROM TIME DISPLAY "Current Date: " CURRENT-DATE DISPLAY "Current Time: " CURRENT-TIME STOP RUN.
Proper error handling is crucial for external interfaces:
123456789CALL "EXTERNAL-PROGRAM" USING PARAM-1 PARAM-2 ON EXCEPTION DISPLAY "ERROR: Program not found or failed" MOVE 8 TO RETURN-CODE STOP RUN NOT ON EXCEPTION DISPLAY "Call successful" END-CALL
123456789101112131415161718EXEC SQL SELECT CUSTOMER_NAME INTO :SQL-CUSTOMER-NAME FROM CUSTOMERS WHERE CUSTOMER_ID = :SQL-CUSTOMER-ID END-EXEC EVALUATE SQLCODE WHEN 0 DISPLAY "Query successful" WHEN 100 DISPLAY "No rows found" WHEN NEGATIVE DISPLAY "SQL Error: " SQLCODE DISPLAY "Error message: " SQLERRM WHEN OTHER DISPLAY "Unexpected SQLCODE: " SQLCODE END-EVALUATE
12345678910111213141516171819FD INPUT-FILE FILE STATUS IS WS-FILE-STATUS. PROCEDURE DIVISION. MAIN-PARA. OPEN INPUT INPUT-FILE IF WS-FILE-STATUS NOT = '00' DISPLAY "File open error: " WS-FILE-STATUS EVALUATE WS-FILE-STATUS WHEN '10' DISPLAY "File not found" WHEN '30' DISPLAY "Permanent I/O error" WHEN OTHER DISPLAY "Unknown error" END-EVALUATE STOP RUN END-IF
Follow these best practices:
123456789101112*> Call service layer program CALL "CUSTOMER-SERVICE" USING BY REFERENCE WS-CUSTOMER-ID BY REFERENCE WS-CUSTOMER-DATA BY REFERENCE WS-SERVICE-STATUS END-CALL IF WS-SERVICE-STATUS = 'SUCCESS' *> Process customer data ELSE *> Handle service error END-IF
1234567*> Encapsulate database access CALL "DB-ACCESS" USING BY REFERENCE WS-QUERY-TYPE BY REFERENCE WS-QUERY-PARAMS BY REFERENCE WS-QUERY-RESULT BY REFERENCE WS-DB-STATUS END-CALL
12345*> Call validation with BY VALUE for safety CALL "VALIDATE-DATA" USING BY VALUE WS-INPUT-DATA BY REFERENCE WS-VALIDATION-RESULT END-CALL
Think of external interfaces like making phone calls:
So external interfaces are ways for your COBOL program to "call" other programs, databases, or services to get help or information - just like making phone calls!
Complete these exercises to reinforce your understanding:
Create a main program that calls an external program to calculate the square of a number. Pass the number and receive the result. Handle the case where the program is not found.
Create a program that demonstrates BY REFERENCE and BY VALUE. Call an external program that modifies parameters, and observe the difference in behavior.
Write a COBOL program that uses embedded SQL to query a customer table. Retrieve customer information based on customer ID and display the results. Handle SQL errors appropriately.
Create a program that calls multiple external programs and handles errors for each. Use different error handling strategies and provide meaningful error messages.
Design a program that calls an external validation service, then calls a database service to store validated data. Handle errors at each step and provide appropriate feedback.
1. What is the primary statement for calling external programs in COBOL?
2. How are parameters passed by default in CALL statements?
3. What do you use to interface with databases in COBOL?
4. What handles errors when a CALLed program cannot be found?
5. What is the main difference between CALL BY REFERENCE and CALL BY VALUE?
6. How do you check for SQL errors after an EXEC SQL statement?