Ank*_*ain 5 postgresql cobol gnucobol embedded-sql
我试图在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.
Run Code Online (Sandbox Code Playgroud)
使用ocesql和编译预编译代码cobc -x
Postgres输出
OPEN SUCCESSFUL
FETCH SUCCESSFUL
003 001
005 001
CLOSE SUCCESSFUL
REOPEN FAILED ERROR: cursor "fetchtbl_c1" already exists
Run Code Online (Sandbox Code Playgroud)
上面的代码在Oracle中运行得非常好(连接部分除外).
Oracle输出
OPEN SUCCESSFUL
FETCH SUCCESSFUL
003 001
CLOSE SUCCESSFUL
REOPEN SUCCESSFUL
Run Code Online (Sandbox Code Playgroud)
我试过在互联网上搜索但没有任何运气.有谁可以帮我这个?我正在使用PostgreSQL版本10.3和GnuCOBOL版本2.2.0.
ocesql预编译器似乎有问题。ocdb.c我已在函数中进行了修复OCDBSetResultStatus,以便在没有结果资源的情况下返回成功的代码(这种情况发生在打开游标的情况下)。
这可能不完全正确,但经过几个小时的测试后,我发现它工作得很好。
\n\n代码更改:
\n\nint\nOCDBSetResultStatus(int id, struct sqlca_t *st){\n struct s_conn *p_conn;\n int retval;\n\n p_conn = look_up_conn_lists(id);\n if(p_conn == NULL){\n //return OCDB_RES_FATAL_ERROR;\n return RESULT_ERROR;\n }\n if(p_conn->resaddr == OCDB_RES_DEFAULT_ADDRESS){\n // \xe7\xb5\x90\xe6\x9e\x9c\xe3\x83\xaa\xe3\x82\xbd\xe3\x83\xbc\xe3\x82\xb9\xe3\x81\x8c\xe7\x84\xa1\xe3\x81\x84\xe3\x81\x9f\xe3\x82\x81\xe6\x88\x90\xe5\x8a\x9f\xe3\x81\xa7\xe8\xbf\x94\xe3\x81\x99\n // Ankit: uncommented since there is no result resource,\n // (true in case of open cursor)\n return OCDB_RES_COMMAND_OK;\n //return RESULT_ERROR;\n }\n\n#ifdef PGSQL_MODE_ON\n retval = OCDB_PGSetResultStatus(p_conn->resaddr,st);\n#endif\n return retval;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n如果有人因这一变化而遇到任何问题,请告诉我。
\n