COBOL - 資料庫介面



到目前為止,我們已經學習了在 COBOL 中使用檔案的方法。現在,我們將討論 COBOL 程式如何與 DB2 互動。它涉及以下術語:

  • 嵌入式 SQL
  • DB2 應用程式程式設計
  • 主機變數
  • SQLCA
  • SQL 查詢
  • 遊標

嵌入式 SQL

嵌入式 SQL 語句用於 COBOL 程式中執行標準 SQL 操作。在應用程式程式編譯之前,嵌入式 SQL 語句由 SQL 處理器預處理。COBOL 被稱為宿主語言。COBOL-DB2 應用程式是指包含 COBOL 和 DB2 的應用程式。

嵌入式 SQL 語句的工作方式與普通 SQL 語句類似,但有一些細微的差別。例如,查詢的輸出被定向到一組預定義的變數,這些變數稱為主機變數。在 SELECT 語句中添加了 INTO 子句。

DB2 應用程式程式設計

以下是編寫 COBOL-DB2 程式時需要遵循的規則:

  • 所有 SQL 語句必須用EXEC SQLENDEXEC分隔。

  • SQL 語句必須在 B 區編碼。

  • 程式中使用的所有表都必須在 WorkingStorage 部分宣告。這是透過使用INCLUDE語句完成的。

  • 除了 INCLUDE 和 DECLARE TABLE 之外的所有 SQL 語句都必須出現在 Procedure Division 中。

主機變數

主機變數用於接收來自表的資料或將資料插入表中。必須為要在程式和 DB2 之間傳遞的所有值宣告主機變數。它們在 Working-Storage 部分宣告。

主機變數不能是組項,但可以組合到主機結構中。它們不能重新命名重新定義。在 SQL 語句中使用主機變數時,在其前面加上冒號 (:)

語法

以下是宣告主機變數並在 Working-Storage 部分包含表的語法:

DATA DIVISION.
   WORKING-STORAGE SECTION.
   
   EXEC SQL
   INCLUDE table-name
   END-EXEC.

   EXEC SQL BEGIN DECLARE SECTION
   END-EXEC.
   
   01 STUDENT-REC.
      05 STUDENT-ID PIC 9(4).
      05 STUDENT-NAME PIC X(25).
      05 STUDENT-ADDRESS X(50).
   EXEC SQL END DECLARE SECTION
   END-EXEC.

SQLCA

SQLCA 是一個 SQL 通訊區域,透過它 DB2 將 SQL 執行的反饋傳遞給程式。它告訴程式執行是否成功。SQLCA 下有一些預定義的變數,例如SQLCODE,其中包含錯誤程式碼。SQLCODE 中的值“000”表示執行成功。

語法

以下是宣告 Working-Storage 部分的 SQLCA 的語法:

DATA DIVISION.
WORKING-STORAGE SECTION.
	EXEC SQL
	INCLUDE SQLCA
	END-EXEC.

SQL 查詢

假設我們有一個名為“Student”的表,其中包含 Student-Id、Student-Name 和 Student-Address。

STUDENT 表包含以下資料:

Student Id		Student Name		Student Address
1001 			   Mohtashim M.		Hyderabad
1002			   Nishant Malik		Delhi
1003 			   Amitabh Bachan		Mumbai
1004			   Chulbul Pandey		Lucknow

以下示例顯示了在 COBOL 程式中使用SELECT查詢的方法:

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.

DATA DIVISION.
   WORKING-STORAGE SECTION.
   EXEC SQL
      INCLUDE SQLCA
   END-EXEC.
   
   EXEC SQL
      INCLUDE STUDENT
   END-EXEC.
   
   EXEC SQL BEGIN DECLARE SECTION
   END-EXEC.
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
   EXEC SQL END DECLARE SECTION
   END-EXEC.

PROCEDURE DIVISION.
   EXEC SQL
      SELECT STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS
      INTO :WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS FROM STUDENT
      WHERE STUDENT-ID=1004
   END-EXEC.
   
   IF SQLCODE = 0 
      DISPLAY WS-STUDENT-RECORD
   ELSE DISPLAY 'Error'
   END-IF.
STOP RUN.

執行上述 COBOL 程式的JCL

//SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
//STEP001  EXEC PGM = IKJEFT01
//STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP = SHR
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//SYSTSIN  DD *
   DSN SYSTEM(SSID)
   RUN PROGRAM(HELLO) PLAN(PLANNAME) -
   END
/*

編譯並執行上述程式後,將產生以下結果:

1004 Chulbul Pandey		Lucknow

以下示例顯示了在 COBOL 程式中使用INSERT查詢的方法:

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.

DATA DIVISION.
   WORKING-STORAGE SECTION.
   EXEC SQL
   INCLUDE SQLCA
   END-EXEC.
   
   EXEC SQL
   INCLUDE STUDENT
   END-EXEC.
   
   EXEC SQL BEGIN DECLARE SECTION
   END-EXEC.
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
   EXEC SQL END DECLARE SECTION
   END-EXEC.

PROCEDURE DIVISION.
   MOVE 1005 TO WS-STUDENT-ID.
   MOVE 'TutorialsPoint' TO WS-STUDENT-NAME.
   MOVE 'Hyderabad' TO WS-STUDENT-ADDRESS.
   
   EXEC SQL
      INSERT INTO STUDENT(STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS)
      VALUES (:WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS)
   END-EXEC.
   
   IF SQLCODE = 0 
      DISPLAY 'Record Inserted Successfully'
      DISPLAY WS-STUDENT-REC
   ELSE DISPLAY 'Error'
   END-IF.
STOP RUN.

執行上述 COBOL 程式的JCL

//SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
//STEP001  EXEC PGM = IKJEFT01
//STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP=SHR
//SYSPRINT DD SYSOUT = *
//SYSUDUMP DD SYSOUT = *
//SYSOUT   DD SYSOUT = *
//SYSTSIN  DD *
   DSN SYSTEM(SSID)
   RUN PROGRAM(HELLO) PLAN(PLANNAME) -
   END
/*

編譯並執行上述程式後,將產生以下結果:

Record Inserted Successfully
1005 TutorialsPoint		Hyderabad

以下示例顯示了在 COBOL 程式中使用UPDATE查詢的方法:

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.

DATA DIVISION.
   WORKING-STORAGE SECTION.
   
   EXEC SQL
   INCLUDE SQLCA
   END-EXEC.
   
   EXEC SQL
   INCLUDE STUDENT
   END-EXEC.
   
   EXEC SQL BEGIN DECLARE SECTION
   END-EXEC.
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
   EXEC SQL END DECLARE SECTION
   END-EXEC.

PROCEDURE DIVISION.
   MOVE 'Bangalore' TO WS-STUDENT-ADDRESS.
   EXEC SQL
      UPDATE STUDENT SET STUDENT-ADDRESS=:WS-STUDENT-ADDRESS
      WHERE STUDENT-ID = 1003
   END-EXEC.
   
   IF SQLCODE = 0 
      DISPLAY 'Record Updated Successfully'
   ELSE DISPLAY 'Error'
   END-IF.
STOP RUN.

執行上述 COBOL 程式的JCL

//SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
//STEP001  EXEC PGM = IKJEFT01
//STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP = SHR
//SYSPRINT DD SYSOUT = *
//SYSUDUMP DD SYSOUT = *
//SYSOUT   DD SYSOUT = *
//SYSTSIN  DD *
   DSN SYSTEM(SSID)
   RUN PROGRAM(HELLO) PLAN(PLANNAME) -
   END
/*

編譯並執行上述程式後,將產生以下結果:

Record Updated Successfully

以下示例顯示了在 COBOL 程式中使用DELETE查詢的方法:

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.

DATA DIVISION.
WORKING-STORAGE SECTION.

   EXEC SQL
   INCLUDE SQLCA
   END-EXEC.
   
   EXEC SQL
   INCLUDE STUDENT
   END-EXEC.
   
   EXEC SQL BEGIN DECLARE SECTION
   END-EXEC.
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
   EXEC SQL END DECLARE SECTION
   END-EXEC.

PROCEDURE DIVISION.
   MOVE 1005 TO WS-STUDENT-ID.
   
   EXEC SQL
      DELETE FROM STUDENT
      WHERE STUDENT-ID=:WS-STUDENT-ID
   END-EXEC.
   
   IF SQLCODE = 0 
      DISPLAY 'Record Deleted Successfully'
   ELSE DISPLAY 'Error'
   END-IF.
STOP RUN.

執行上述 COBOL 程式的JCL

//SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
//STEP001  EXEC PGM = IKJEFT01
//STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP=SHR
//SYSPRINT DD SYSOUT = *
//SYSUDUMP DD SYSOUT = *
//SYSOUT   DD SYSOUT = *
//SYSTSIN  DD *
   DSN SYSTEM(SSID)
   RUN PROGRAM(HELLO) PLAN(PLANNAME) -
   END
/*

編譯並執行上述程式後,將產生以下結果:

Record Deleted Successfully

遊標

遊標用於一次處理多個行選擇。它們是儲存查詢所有結果的資料結構。它們可以在 Working-Storage 部分或 Procedure Division 中定義。以下是與遊標相關的操作:

  • 宣告
  • 開啟
  • 關閉
  • 提取

宣告遊標

遊標宣告可以在 Working-Storage 部分或 Procedure Division 中完成。第一個語句是 DECLARE 語句,它是一個非可執行語句。

EXEC SQL
   DECLARE STUDCUR CURSOR FOR
   SELECT STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS FROM STUDENT
   WHERE STUDENT-ID >:WS-STUDENT-ID
END-EXEC.

開啟

在使用遊標之前,必須執行 Open 語句。Open 語句準備執行 SELECT。

EXEC SQL
   OPEN STUDCUR
END-EXEC.

關閉

Close 語句釋放遊標佔用的所有記憶體。在結束程式之前關閉遊標是強制性的。

EXEC SQL
   CLOSE STUDCUR
END-EXEC.

提取

Fetch 語句識別遊標並將值放入 INTO 子句中。Fetch 語句在迴圈中編碼,因為我們一次獲取一行。

EXEC SQL
   FETCH STUDCUR
   INTO :WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS
END-EXEC.

以下示例顯示瞭如何使用遊標從 STUDENT 表中提取所有記錄:

IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.

DATA DIVISION.
   WORKING-STORAGE SECTION.
   
   EXEC SQL
   INCLUDE SQLCA
   END-EXEC.
   
   EXEC SQL
   INCLUDE STUDENT
   END-EXEC.
   
   EXEC SQL BEGIN DECLARE SECTION
   END-EXEC.
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
   EXEC SQL END DECLARE SECTION
   END-EXEC.
   
   EXEC SQL
      DECLARE STUDCUR CURSOR FOR
      SELECT STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS FROM STUDENT
      WHERE STUDENT-ID >:WS-STUDENT-ID
   END-EXEC.

PROCEDURE DIVISION.
   MOVE 1001 TO WS-STUDENT-ID.
   PERFORM UNTIL SQLCODE = 100
   
   EXEC SQL
      FETCH STUDCUR
      INTO :WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS
   END-EXEC
   
   DISPLAY WS-STUDENT-REC
END-PERFORM	
STOP RUN.

執行上述 COBOL 程式的JCL

//SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
//STEP001  EXEC PGM=IKJEFT01
//STEPLIB  DD DSN=MYDATA.URMI.DBRMLIB,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//SYSTSIN  DD *
   DSN SYSTEM(SSID)
   RUN PROGRAM(HELLO) PLAN(PLANNAME) -
   END
/*

編譯並執行上述程式後,將產生以下結果:

1001 Mohtashim M.		Hyderabad
1002 Nishant Malik		Delhi
1003 Amitabh Bachan		Mumbai
1004 Chulbul Pandey		Lucknow
廣告