Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GnuCOBOL中的PostgreSQL游标重新打开错误_Postgresql_Cobol_Gnucobol_Embedded Sql - Fatal编程技术网

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

GnuCOBOL中的PostgreSQL游标重新打开错误,postgresql,cobol,gnucobol,embedded-sql,Postgresql,Cobol,Gnucobol,Embedded Sql,我正试图在GnuCOBOL上从Oracle迁移到PostgreSQL。我有一段使用游标的代码,需要多次打开游标。但是,当再次尝试打开光标时,出现错误错误:光标“fetchtbl_c1”已经存在 IDENTIFICATION DIVISION. PROGRAM-ID. FETCHTBL. DATA DIVISION. WORKIN

我正试图在GnuCOBOL上从Oracle迁移到PostgreSQL。我有一段使用游标的代码,需要多次打开游标。但是,当再次尝试打开光标时,出现错误
错误:光标“fetchtbl_c1”已经存在

        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

博士后输出

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。

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

这可能不完全正确,但在花了几个小时进行测试后,我发现它工作得很好

代码更改:

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;
}

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

暗中猜测:您能否尝试
取消分配
准备好的语句(在光标后面)?我没有使用prepare语句。正如上面的代码所示,它是一个直接的光标。问题是如果我要使用prepared语句,我有1000个组件需要更改。我的想法是游标隐式地创建(或使用)一个prepared语句(从Postgres的角度来看)。关闭光标后的
解除分配所有
可以验证这一理论。只是尝试了一下,遗憾的是这不起作用。在
DEALLOCATE ALL
成功后,我检查了
SQLCODE
,但仍然得到相同的错误
error:cursor“fetchtbl_c1”已经存在
您使用了什么版本的ocesql和什么操作系统?您是否也尝试过[esqlOC](?这意味着使用COBOLODBC(通过ocsql库)PostgreSQL。注意:我已经检查了您的示例代码,esqlOC目前不支持
DISCONNECT
,但至少添加
DISCONNECT ALL
应该可以快速完成。但这只有在其他部分适合您的情况下才有意义……似乎是一个合理的PR,可以发布,同时还创建一个包含您的示例的问题问题中张贴的代码、您的解释和参考PR。