我有下面的 SQLRPGLE 代码显示了我的访问和关闭 - 但在程序运行后,文件(MONEWAS3 和 WELFARE)保持打开状态,通过查看会话的“显示打开文件”进行验证。如果我注销并重新登录,它们显然会关闭,但再次运行程序将打开并让它们保持打开状态。
当我编译代码(CRTSQLRPGI)时,我将 CLOSQLCSR 更改为 *ENDMOD。
关于我做错了什么导致文件保持打开状态有什么想法吗?
ctl-opt dftactgrp(*no);
dcl-f MOCL0700DP printer oflind(PageOverflow) ;
dcl-s PageOverflow ind;
dcl-s count uns(10);
dcl-s inFund zoned(4);
dcl-s inDateRec zoned(8);
dcl-s inFedId packed(9:0);
dcl-s inPayPer zoned(8);
dcl-s inLname char(20);
dcl-s inFinit char(1);
dcl-s inMinit char(1);
dcl-s inSocSec packed (9:0);
dcl-s inAreaW zoned(4);
dcl-s inHomeW zoned(4);
nextPage();
exec sql create alias qtemp.monewas3a FOR MONEWAS3(AS30700);
exec sql declare C0 cursor for
SELECT ALL T01.FUND, T01.DATREC, T01.FEDID, T01.PAYPER, T01.LNAME,
T01.FINIT, T01.MINIT, T01.SOCSEC, T02.AREAW, T02.HOMEW
FROM monewas3a T01
INNER JOIN WELFARE T02 ON T01.SOCSEC = T02.SOCSEC
WHERE FUND = AREAW AND HOMEW <> 0322
ORDER BY T01.DATREC ASC, T01.FEDID ASC, T01.PAYPER ASC,
T01.LNAME ASC;
exec sql open C0;
dow (1=1);
exec sql fetch next from C0 into :inFund, :inDatRec, :inFedId,
:inPayPer, :inLname, :inFinit, :inMinit, :inSocSec, inAreaW,
:inHomeW;
if sqlcod <> 0;
leave;
endif;
if Pageoverflow;
nextPage();
endif;
write DETAIL;
count += 1;
enddo;
exec sql close C0 ;
exec sql drop alias qtemp.monewas3a;
if count = 0;
write ERR01;
endif;
*inlr = *on;
close *all;
dcl-proc nextPage;
pageoverflow = *off;
write HDG01;
end-proc;
我怀疑,由于您在别名上创建游标,因此 SQL 操作被视为动态操作,因此您遇到了伪关闭游标
伪关闭游标是性能优化的关键部分 IBM DB2 for i SQL 的功能。当应用程序关闭游标时,Db2 for i 通常关闭光标并关闭文件,删除 ODP (打开数据路径)。如果应用程序多次运行同一条语句 有时,每次新的执行都需要完全打开目标文件。这 伪关闭游标背后的想法是不完全关闭游标并且 文件,而是缓存光标以供将来使用。
运行程序后,尝试发出
ALCOBJ OBJ((MONEWAS3 *FILE *EXCL)) CONFLICT(*RQSRLS)
如果文件现在已关闭,则您已确认问题是光标已被操作系统伪关闭。
如果是这样的话,那就是“按设计工作”
该行为不应该成为问题,如果是问题......这通常是处理过程的其他部分正在执行与现代应用程序不兼容的操作的标志。
编辑
CLRPFM
例如 CL 命令,很长一段时间(也许仍然)是一个问题。但 SQL DELETE
或 TRUNCATE
工作得很好。