我正在尝试从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
进行编译
后置输出
OPEN SUCCESSFUL
FETCH SUCCESSFUL
003 001
005 001
CLOSE SUCCESSFUL
REOPEN FAILED ERROR: cursor "fetchtbl_c1" already exists
上面的代码在 Oracle 中运行良好(连接部分除外(。
甲骨文输出
OPEN SUCCESSFUL
FETCH SUCCESSFUL
003 001
CLOSE SUCCESSFUL
REOPEN SUCCESSFUL
我尝试过在互联网上搜索,但没有任何运气。有人可以帮助我吗?我正在使用PostgreSQL版本10.3和GnuCOBOL版本2.2.0。
预编译器似乎ocesql
问题。我已经在函数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;
}
如果有人因此更改而面临任何问题,请告诉我。