【问题标题】:What is causing this DB2 for i SQL oddity?是什么导致了这个 DB2 for i SQL 异常?
【发布时间】:2017-01-05 08:20:34
【问题描述】:

我们遇到了一个 SQLRPGLE 程序无法将数据加载到屏幕的持续性间歇性问题。一位同事刚刚弄清楚如何可靠地重现它,所以我一直在调试器中进行调查。

程序向远程系统打开一个 SQL 游标以填充子文件,如果用户按 F5,它会关闭游标并重新打开它。在某些情况下,这会以一种有趣的方式失败。

发现的可重复过程是先运行函数,退出,然后发出 STRSQL(显示远程连接仍处于活动状态)和 CONNECT RESET。然后退出命令行并重新启动该函数。这在第一次显示和按 F5 一次后有效。但第二次按 F5 时光标变得奇怪,程序无法加载数据。

这是我在调试器中运行的事件序列以及每个关键 SQL 函数之后的 SQLSTATE 值。我检查了每个显示的第一个 FETCH,就像进行完整性检查一样。每次连接都会重新连接(可能是不必要的)远程系统。

Action          SQLSTATE    Meaning
Initial connect 0           OK
Open cursor     0           OK
First fetch     0           OK
F5 pressed      
Close cursor    0           OK
Reconnect       8002        Already connected
Open cursor     0           OK
First fetch     0           OK
F5 pressed
Close cursor    0           OK
Reconnect       8002        Already connected
Open cursor     0           OK
First fetch     0           OK
Exit program            
Close cursor    0           OK
STRSQL CONNECT      
Reconnect       8002        Already connected
Open cursor     0           OK
First fetch     0           OK
F5 pressed      
Close cursor    0           OK
Reconnect       8002        Already connected
Open cursor     0           OK
First fetch     0           OK
F5 pressed      
Close cursor    0           OK
Reconnect       8002        Already connected
Open cursor     24502       Already open
First fetch     24501       Cursor not open

在 CONNECT RESET 运行之前,按 F5 的循环无限期地工作。

退出函数后,返回依然显示空列表(即光标问题依然存在)但是如果程序的激活组被回收,那么第一次显示和第一次F5又起作用了,但是第二次F5导致光标再发一次。

我尝试运行 RUNSQL SQL('CONNECT RESET') 失败,说明尚未达到承诺边界。它没有更新任何文件,所以不确定这可能是什么问题。我们确实发现在 CONNECT 重置之前在 STRSQL 中运行 COMMIT 确实可以解决问题,但只是暂时的,就像回收激活组一样。

我们还尝试在模块上将提交控制设置为 *NONE 并将 Close SQL Cursor 设置为 *ENDMOD,但似乎都没有任何区别。

我们当然会很感激任何关于其他内容的建议!

【问题讨论】:

  • 什么版本和发行版?您是否了解 PTF 的最新情况?
  • V6R1M1 是的,在 PTF 上相当流行。

标签: sql cursor ibm-midrange db2-400


【解决方案1】:

光标打开意味着模块永远不会结束并关闭光标。
sqlrpgle 程序不得不中止一些事情。

数据小数错误,选择多行的结果,字段太大,无法插入或更新。

sql 错误的最佳做法是在 sqlcode 为负数时使用转储命令。

if sqlcode < 0 
    dump
endif

在打开光标之前关闭热修复。但请记住,您的程序退出仍有一个原因需要修复。

close mycursor;
open mycursor;

【讨论】:

  • 如动作列表所示,当程序退出时,光标成功关闭。
  • 我将添加 SQLCODE
  • 因此,如果仅在引入连接后失败,请尝试使用连接重置。
  • 有趣的是,如果我退出该函数并立即再次运行它,这样做会导致问题发生。但是,如果我收回 QILE 激活组并重试,它会得到修复。
  • 我们很难讨论。 As shown in the list of actions... 不幸的是,没有显示;而是显示一个文本常量 (Exit program)。我们知道这是因为it is fixed if I reclaim the QILE activation group。也就是说,几乎可以肯定会执行某种类型的 RETURN,但程序并没有完全“退出”。该程序仍处于激活状态,因为结束 AG“修复”了该问题。当控制 AG 未被回收时,简单地离开(返回)程序与“退出”程序并不完全相同。
【解决方案2】:

虽然我仍然不明白最后两个事件如何按顺序有效,但我找到了一种方法来阻止 CONNECT(外部或其他)成为问题。

在 CRTSQLRPGI 命令上有一个参数:

RDB connect method . . . . . . .   *DUW          *DUW, *RUW

*RUW 的帮助文本让我觉得值得一试:

*RUW                                                                   
CONNECT (Type 1) semantics are used to support remote unit of work.
Consecutive CONNECT statements result in the previous connection   
being disconnected before a new connection is established.         

我发现RDBCNNMTH(*RUW) 结合COMMIT(*NONE) 可以解决问题。

我认为这是一种解决方法,但确实可行。

【讨论】:

    【解决方案3】:

    这听起来很简单...当您按 F5 时,*IN05 应该关闭,按此键将其打开。这个动作应该激活你正在做的任何事情。 -如果-进程循环中的某些东西踩到*IN05,现在让它*ON(假设您在函数触发时将其关闭)所以当它回滚时,连接已经建立。只是添加一个想法,因为听起来您的 SQL 确实很可靠。

    【讨论】:

    • 有趣的想法,谢谢。我已经在脑海中反复思考过你的理论,但我仍然无法克服最后两个动作的矛盾——这表明光标既打开又不打开,中间没有 (SQL) 操作。
    猜你喜欢
    • 2014-11-07
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 2019-08-10
    相关资源
    最近更新 更多