GnuCOBOL 中的 PostgreSQL 游标重新打开错误

PostgreSQL Cursor Re-open error in GnuCOBOL

我正在尝试从 Oracle 迁移到 GnuCOBOL 上的 PostgreSQL。我有一段使用游标的代码,需要多次打开游标。但是,当再次尝试打开光标时,出现错误 ERROR: cursor "fetchtbl_c1" already exists

        IDENTIFICATION              DIVISION.
        PROGRAM-ID.                 FETCHTBL.

        DATA                        DIVISION.
        WORKING-STORAGE             SECTION.
        01  D-SOC-REC.
            05  D-SOC-NO-1          PIC  X(3).
            05  FILLER              PIC  X.
            05  D-SOC-NO-2          PIC  X(3).

        EXEC SQL BEGIN DECLARE SECTION END-EXEC.
        01  USERNAME                PIC  X(30) VALUE SPACE.
        01  SOC-REC-VARS.
            05  SOC-NO-1            PIC X(3).
            05  SOC-NO-2            PIC X(3).
        EXEC SQL END DECLARE SECTION END-EXEC.

        EXEC SQL INCLUDE SQLCA END-EXEC.
        PROCEDURE                   DIVISION.
        MAIN-RTN.
            MOVE  SPACE             TO   USERNAME.
            EXEC SQL
                CONNECT :USERNAME
            END-EXEC.
            IF  SQLCODE NOT = ZERO DISPLAY "ERROR CONNECTING".

       *    DECLARE CURSOR
            EXEC SQL
                DECLARE C1 CURSOR FOR
                SELECT SOC_NO_1, SOC_NO_2
                       FROM INSP
                       ORDER BY SOC_NO_1
            END-EXEC.
            EXEC SQL
                OPEN C1
            END-EXEC.
            IF SQLCODE = ZERO DISPLAY "OPEN SUCCESSFUL"
            ELSE DISPLAY "OPEN FAILED".

       *    FETCH
            EXEC SQL
                FETCH C1 INTO :SOC-NO-1,:SOC-NO-2
            END-EXEC.
            IF SQLCODE = ZERO DISPLAY "FETCH SUCCESSFUL"
            ELSE DISPLAY "FETCH FAILED".
            PERFORM UNTIL SQLCODE NOT = ZERO
               MOVE  SOC-NO-1      TO    D-SOC-NO-1
               MOVE  SOC-NO-2      TO    D-SOC-NO-2
               DISPLAY D-SOC-REC
               EXEC SQL
                   FETCH C1 INTO :SOC-NO-1,:SOC-NO-2
               END-EXEC
            END-PERFORM.

       *    CLOSE CURSOR
            EXEC SQL
                CLOSE C1
            END-EXEC.
            IF SQLCODE = ZERO DISPLAY "CLOSE SUCCESSFUL"
            ELSE DISPLAY "CLOSE FAILED".

       *    OPEN AGAIN
            EXEC SQL
                OPEN C1
            END-EXEC.
            IF SQLCODE = ZERO DISPLAY "REOPEN SUCCESSFUL"
            ELSE DISPLAY "REOPEN FAILED " SQLERRMC.
       *    COMMIT
            EXEC SQL
                COMMIT WORK
            END-EXEC.

       *    DISCONNECT
            EXEC SQL
                DISCONNECT ALL
            END-EXEC.

       *    END
            STOP RUN.

使用 ocesql 预编译代码并使用 cobc -x

编译

Postgres 输出

OPEN SUCCESSFUL
FETCH SUCCESSFUL
003 001
005 001
CLOSE SUCCESSFUL
REOPEN FAILED ERROR:  cursor "fetchtbl_c1" already exists

以上代码在 Oracle 中运行良好(连接部分除外)。

Oracle 输出

OPEN SUCCESSFUL
FETCH SUCCESSFUL
003 001
CLOSE SUCCESSFUL
REOPEN SUCCESSFUL

我试过在互联网上搜索但没有成功。任何人都可以帮助我吗? 我使用的是 PostgreSQL 10.3 版和 GnuCOBOL 2.2.0 版。

ocesql 预编译器似乎有问题。我已经在函数 OCDBSetResultStatus 中的 ocdb.c 中修复了 return 一个成功的代码,以防没有结果资源(这发生在打开的游标情况下)。

这可能不完全正确,但经过几个小时的测试后,我发现它工作正常。

代码更改:

int
OCDBSetResultStatus(int id, struct sqlca_t *st){
    struct s_conn *p_conn;
    int retval;

    p_conn = look_up_conn_lists(id);
    if(p_conn == NULL){
      //return OCDB_RES_FATAL_ERROR;
        return RESULT_ERROR;
    }
    if(p_conn->resaddr == OCDB_RES_DEFAULT_ADDRESS){
        // 結果リソースが無いため成功で返す
        // Ankit: uncommented since there is no result resource,
        //        (true in case of open cursor)
        return OCDB_RES_COMMAND_OK;
        //return RESULT_ERROR;
    }

#ifdef PGSQL_MODE_ON
    retval = OCDB_PGSetResultStatus(p_conn->resaddr,st);
#endif
    return retval;
}

如果有人因为此更改而遇到任何问题,请告诉我。