我正试图在GnuCOBOL上从Oracle迁移到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。
答案 0 :(得分:0)
ocesql
预编译器似乎存在问题。我在函数ocdb.c
中的OCDBSetResultStatus
中修复了一个成功的代码,以防止没有结果资源(对于打开游标的情况会发生这种情况)。
这可能不完全正确但经过几个小时的测试后我发现这个工作正常。
代码更改:
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;
}
如果有人因为这种变化而面临任何问题,请告诉我。