我正在使用 DB2 for IBM i(一个 iSeries (AS/400)),在 Zend Server 8.0.2 上使用 PHP 5.6.5 和 ibm_db2 驱动程序。
我遇到了一个实例,其中包含别名为名称的子选择的视图可能会或可能不会返回多行。我没有创建视图,我理解错误并且可以纠正它。奇怪的是,在 PHP 中,错误不会在 db2_exec() 上引发,而是在 db2_fetch_assoc() 上引发。我开始研究它,但找不到优雅地检测 db2_fetch_assoc() 生成的错误的方法。它在 Zend 错误日志中记录为“db2_fetch_assoc(): Fetch Failure”,E_WARNING 状态。
db2_stmt_error()
并且db2_stmt_errormsg()
只返回与 、 和 相关db2_exec()
的db2_execute()
错误db2_prepare()
。我什至尝试使用类似的东西:
try{
//fetch record
}catch(Exception $exc){
print_r($exc);
}
并且它不会注册为异常。
我能想到的最好方法是发出初步查询以获取应返回的行数。然后使用这样的 for 循环:
for($rows = 0; $rows < $ttlRows; $rows++){
if($row = db2_fetch_assoc($stmt, $rows)){
//Do some stuff
}else{
//Still never get to see information about the error or the afflicted row.
}
}
有谁知道优雅地检测、跟踪或处理此类实例的任何其他方法?
EDIT1:
我设法在这里找到值得一提的东西:PHP:如何优雅地管理错误?
这个答案描述了当警告发生时如何强制异常(这是我从 中得到的db2_fetch_assoc()
)。不利的一面是,如果没有发现任何警告,都会导致页面执行停止。
我正在考虑的想法是将我的整个页面包装在一个不执行任何操作的try-catch
子句中catch
(比如包含try{
在页眉包含和}catch(Exception $exc){}
页脚包含中)。这将允许页面执行,并且由于try-catch
允许嵌套子句,我仍然可以像往常一样使用 try-catch。不过好像很脏。
EDIT2:
只是澄清一下,我并不是想弄清楚我遇到了什么错误或如何纠正它 - 我已经知道它是什么以及如何纠正它。但是为了记录,我得到的错误是这里SQL0811
定义的。我想弄清楚的是如何检测并优雅地处理由db2_fetch_assoc()
. 原因是因为如果我没有检测到它,那么提取过程将在第一个受影响的记录上抢先结束,但页面将呈现好像一切都很好。因此,对于未来,我希望有一个安全措施来检测这些情况,而不是在几个月后意识到某些事情无法正常工作。不幸的是,我在第一次编辑中发布的次要解决方案不是一个可行的解决方案,因为它真正报告的只是发生了一次提取失败 - 与失败的原因无关。这是一些东西,但不多。理想情况下,我想有一种方法可以获取 SQL 状态代码或其他东西(对于我的错误,可能是以下任何一个:SQL0811、-811、21000,它们在上面的链接中定义)。
此外,我无法弄清楚为什么 SQL 错误仅被视为 php.ini 中的 E_WARNING。对我来说似乎有点奇怪,但我在 iNavigator 中得到了相同的行为(即,它仅在您到达受影响的行时才会死亡)但不是绿屏(这会在查询执行时引发错误)。所以它必须与数据库驱动程序以及它们如何处理这个有关。