COBOL2002 使用の手引 手引編


23.1.2 プログラムの例

埋め込みSQL文を使って,データベースの表にアクセスする例を示します。表は,DBMSが提供するツールなどを使用して定義します。詳細は,使用するDBMSのSQLリファレンスなどを参照してください。

なお,ここに示すのは,HiRDBを使用した場合のアクセス方法の例です。

〈この項の構成〉

(1) 静的に行う方法によるプログラムの例

(a) 表の定義

氏名と住所にそれぞれ対応する,PERSONNAME列とPERSONADDRESS列を持つ「ADDRESSBOOK」という住所録の表を定義します。

           CREATE TABLE ADDRESSBOOK ( PERSONNAME char(20),
                                 PERSONADDRESS varchar(255))

(b) 表へのアクセス

「ADDRESSBOOK」の表にアクセスします。

すでに表へ登録されている人の場合,住所を更新します。また,登録されていない人の場合,住所と氏名を新規に登録します。

      * <埋め込みSQL宣言節>
           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
           01 ODBC-DSN PIC X(10) VALUE 'SAMPLE'.
           01 ODBC-UID PIC X(10) VALUE 'USER1'.
           01 ODBC-PWD PIC X(10) VALUE 'USER1'.
           01 行数     PIC S9(9) USAGE COMP VALUE ZERO.
           01 ADDRESSBOOK.
            02 PERSONNAME    PIC  X(20).
            02 PERSONADDRESS.
             03 ODBC-length PIC S9(9) USAGE COMP.
             03 ODBC-char   PIC  X(255).
           EXEC SQL END DECLARE SECTION END-EXEC.
          :
       PROCEDURE DIVISION.
          :
      * <埋め込み例外宣言>
           EXEC SQL WHENEVER SQLERROR STOP END-EXEC.
      * <コネクションの確立>
           EXEC SQL
             CONNECT  :ODBC-UID  IDENTIFIED BY :ODBC-PWD
             USING    :ODBC-DSN
           END-EXEC.
      * <埋め込み例外宣言>
           EXEC SQL WHENEVER SQLERROR
                    GO TO :ROLLBACK-PROC END-EXEC.
           EXEC SQL WHENEVER NOT FOUND
                    PERFORM :NOTFOUND-PROC END-EXEC. 
      * <登録されているかを参照する>
           MOVE '日立 太郎' TO PERSONNAME.
           MOVE '福岡市博多区1丁目' TO ODBC-char OF PERSONADDRESS.
           MOVE 27 TO ODBC-length OF PERSONADDRESS.
           EXEC SQL
             SELECT COUNT(*) INTO :行数 FROM ADDRESSBOOK
             WHERE PERSONNAME = :PERSONNAME
           END-EXEC.
      * <住所録の表に登録する>
           IF 行数 = 0 THEN
             EXEC SQL
               INSERT INTO ADDRESSBOOK ( PERSONNAME, PERSONADDRESS)
               VALUES ( :PERSONNAME, :PERSONADDRESS)
             END-EXEC
      * <住所録の表の住所を更新する>
           ELSE
             EXEC SQL
               UPDATE ADDRESSBOOK SET PERSONADDRESS = :PERSONADDRESS
                             WHERE PERSONNAME = :PERSONNAME
             END-EXEC
           END-IF.
           EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
           EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC.
           EXEC SQL
             COMMIT WORK
           END-EXEC.
           GO TO DISCONNECT-PROC.
       ROLLBACK-PROC.
           EXEC SQL
             ROLLBACK WORK
           END-EXEC.
       DISCONNECT-PROC.
           EXEC SQL
             DISCONNECT
           END-EXEC.
           :
           STOP RUN.
       NOTFOUND-PROC SECTION.
           :
       NOTFOUND-PROC-END.
           EXIT.
           :

(2) ストアドプロシージャの呼び出しの例

(a) ストアドプロシージャの定義

(1) 静的に行う方法によるプログラムの例」に示した「ADDRESSBOOK」の表にアクセスします。

すでに表へ登録されている人の場合,住所を更新し,表に未登録の人の場合,住所と氏名を登録するようなストアドプロシージャを定義します。

           CREATE PROCEDURE
             ADDRESSUPDATE (IN @PERSONNAME char(20)
                           , IN @PERSONADDRESS varchar(255) )
           BEGIN
             DECLARE REC_CNT INTEGER;
             SELECT COUNT(*) INTO REC_CNT FROM ADDRESSBOOK
               WHERE PERSONNAME = @PERSONNAME;
             IF 0 = REC_CNT THEN
               INSERT INTO ADDRESSBOOK ( PERSONNAME,PERSONADDRESS )
                 VALUES ( @PERSONNAME,@PERSONADDRESS );
             ELSE
               UPDATE ADDRESSBOOK SET PERSONADDRESS = @PERSONADDRESS
                 WHERE PERSONNAME = @PERSONNAME;
             END IF;
           END

(b) ストアドプロシージャの呼び出し

定義したストアドプロシージャを呼び出します。

      * <埋め込みSQL宣言節>
           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
           :
           01 ADDRESSUPDATE.
             02 PERSONNAME PIC X(20).
             02 PERSONADDRESS.
               03 ODBC-length PIC S9(9) USAGE COMP.
               03 ODBC-char   PIC X(255). 
           EXEC SQL END DECLARE SECTION END-EXEC.
           :
      
       PROCEDURE DIVISION.
           :
      * <住所録の表の住所を更新する>
           MOVE '日立 太郎' TO PERSONNAME.
           MOVE '福岡市博多区2丁目' TO ODBC-char OF PERSONADDRESS.
           MOVE 27 TO ODBC-length OF PERSONADDRESS.
           EXEC SQL
             CALL ADDRESSUPDATE ( :PERSONNAME, :PERSONADDRESS )
           END-EXEC.
           :

(3) 動的に行う方法によるプログラムの例

(a) 表の定義

氏名と住所にそれぞれ対応する,PERSONNAME列とPERSONADDRESS列を持つ「ADDRESSBOOK」という住所録の表を定義します。

           CREATE TABLE ADDRESSBOOK ( PERSONNAME char(20),
                                 PERSONADDRESS varchar(255))

(b) 表へのアクセス

「ADDRESSBOOK」の表にアクセスします。

住所録の表に住所,氏名を登録し,住所録一覧を取得します。

      * <埋め込みSQL宣言節>
           EXEC SQL BEGIN DECLARE SECTION END-EXEC.
          :
           01 動的SQL PIC X(80).
           01 ADDRESSBOOK.
             02 PERSONNAME PIC X(20).
             02 PERSONADDRESS.
               03 ODBC-length PIC S9(9) USAGE COMP.
               03 ODBC-char   PIC X(255).
           EXEC SQL END DECLARE SECTION END-EXEC.
          :
       PROCEDURE DIVISION.
          :
      * <埋め込み例外宣言>
           EXEC SQL WHENEVER SQLERROR
             GO TO :ROLLBACK-PROC END-EXEC.
           EXEC SQL WHENEVER NOT FOUND
             PERFORM :NOTFOUND-PROC END-EXEC. 
      * <住所録の表に登録する>
           MOVE 'INSERT INTO ADDRESSBOOK (PERSONNAME, PERSONADDRESS)'
      -         'VALUES (?,?)' TO 動的SQL.
           EXEC SQL
             PREPARE DYNSQL1 FROM :動的SQL
           END-EXEC.
           MOVE '日立 太郎' TO PERSONNAME.
           MOVE '福岡市博多区3丁目' TO ODBC-char OF PERSONADDRESS.
           MOVE 27 TO ODBC-length OF PERSONADDRESS.
           EXEC SQL
             EXECUTE DYNSQL1 USING :PERSONNAME, :PERSONADDRESS 
           END-EXEC.
           EXEC SQL
             DEALLOCATE PREPARE DYNSQL1
           END-EXEC.
           EXEC SQL 
             COMMIT WORK
           END-EXEC.
      * <住所録の表を一覧表示する>
           MOVE 'SELECT PERSONNAME, PERSONADDRESS FROM ADDRESSBOOK'
             TO 動的SQL.
           EXEC SQL 
             PREPARE DYNSQL1 FROM :動的SQL
           END-EXEC.      
           EXEC SQL
             DECLARE CRS00 CURSOR
               FOR DYNSQL1
           END-EXEC.
           EXEC SQL
             OPEN CRS00
           END-EXEC.
           EXEC SQL
               FETCH CRS00 INTO :PERSONNAME, :PERSONADDRESS
           END-EXEC.
           :
           EXEC SQL
             CLOSE CRS00
           END-EXEC.
           EXEC SQL
             DEALLOCATE PREPARE DYNSQL1
           END-EXEC.
           :

(4) 現行コネクションの変更の例

testdb1の接続先データベースの「ADDRESSBOOK」の表にアクセスし,取得した住所データでtestdb2の接続先データベースの「RECIPIENTS」の表の住所を更新します。

       :
      * <CONNDB1コネクションの確立>
           MOVE 'testdb1' TO ODBC-DSN.
           EXEC SQL
            CONNECT :ODBC-UID IDENTIFIED BY :ODBC-PWD …1.
              USING :ODBC-DSN AS CONNDB1
           END-EXEC.
      * <住所を取得する>
           MOVE '日立 太郎' TO PERSONNAME.
           EXEC SQL
            SELECT PERSONADDRESS INTO :PERSONADDRESS FROM ADDRESSBOOK
                        WHERE PERSONNAME = :PERSONNAME
           END-EXEC.
            :
      * <CONNDB2コネクションの確立>
           MOVE 'testdb2' TO ODBC-DSN.
           EXEC SQL
            CONNECT :ODBC-UID IDENTIFIED BY :ODBC-PWD …2.
              USING :ODBC-DSN AS CONNDB2
           END-EXEC.
      * <取得した住所で更新する>
          MOVE '日立 太郎' TO PERSONNAME.
           EXEC SQL
             UPDATE RECIPIENTS SET PERSONADDRESS = :PERSONADDRESS
               WHERE PERSONNAME = :PERSONNAME
           END-EXEC.
            :
      * <現行コネクション(CONNDB2)を解除>
           EXEC SQL
            DISCONNECT CURRENT …3.
           END-EXEC.
      * <現行コネクションを変更する>
           EXEC SQL
            SET CONNECTION CONNDB1  …4.
           END-EXEC.
            :
例の説明
  1. testdb1への接続を確立。

    CONNDB1が現行コネクションとなる。

  2. testdb2への接続を確立。

    CONNDB2が現行コネクションとなる。

  3. 現行コネクションCONNDB2を解除。

    現行コネクションは不定となる。

  4. 現行コネクションをCONNDB1に変更。

    CONNDB1が現行コネクションとなる。