Php 如果查询成功,如何捕获db2_fetch_assoc()生成的错误?

Php 如果查询成功,如何捕获db2_fetch_assoc()生成的错误?,php,error-handling,ibm-midrange,db2-400,ibm-db2,Php,Error Handling,Ibm Midrange,Db2 400,Ibm Db2,我正在使用DB2forIBMi(一个iSeries(AS/400))使用PHP5.6.5,ZendServer8.0.2上的IBMDB2驱动程序 我遇到过一个实例,其中包含别名为名称的子选择的视图可能返回多行,也可能不返回多行。我没有创建视图,我理解错误并可以更正它。奇怪的是,在PHP中,错误不是在db2_exec()上抛出的,而是在db2_fetch_assoc()上抛出的。我开始研究它,但我找不到一种方法来优雅地检测db2_fetch_assoc()生成的错误。它作为“db2_fetch_a

我正在使用DB2forIBMi(一个iSeries(AS/400))使用PHP5.6.5,ZendServer8.0.2上的IBMDB2驱动程序

我遇到过一个实例,其中包含别名为名称的子选择的视图可能返回多行,也可能不返回多行。我没有创建视图,我理解错误并可以更正它。奇怪的是,在PHP中,错误不是在db2_exec()上抛出的,而是在db2_fetch_assoc()上抛出的。我开始研究它,但我找不到一种方法来优雅地检测db2_fetch_assoc()生成的错误。它作为“db2_fetch_assoc():fetch Failure”E_警告状态记录在Zend错误日志中

db2\u stmt\u error()
db2\u errormsg()
只返回与
db2\u exec()
db2\u execute()
db2\u 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.
        }
    }
for($rows=0;$rows<$ttlRows;$rows++){
if($row=db2\u fetch\u assoc($stmt,$rows)){
//做点什么
}否则{
//仍然无法查看有关错误或受影响行的信息。
}
}
是否有人知道任何其他方法可以优雅地检测、跟踪或处理此类实例

EDIT1: 我在这里找到了一些值得一提的东西: 这个答案描述了在出现警告时如何强制执行异常(这是我从
db2\u fetch\u assoc()
中得到的)。缺点是,任何警告如果未被捕获,都会导致页面执行停止

我的娱乐想法是将我的整个页面包装在一个
try-catch
子句中,
catch
不做任何事情(比如在页眉include中包含
try{
,在页脚include中包含
}catch(异常$exc){}
)。这将允许页面执行,因为嵌套的
try-catch
子句是允许的,所以我仍然可以像平常一样使用try-catch。虽然看起来很脏

EDIT2: 我只是想澄清一下,我并不是想弄清楚我犯了什么错误或者如何纠正它——我已经知道它是什么,以及如何纠正它。但是对于记录,我得到的错误是定义的
SQL0811
。我想弄明白的是如何检测并优雅地处理由
db2\u fetch\u assoc()生成的E\u警告。原因是,如果我没有检测到它,那么抓取过程将在第一条受影响的记录上抢先结束,但页面将呈现为一切正常。因此,对于未来,我希望有一个适当的保护措施,能够检测到这些情况,而不是在接下来的几个月里意识到有些东西工作不正常。不幸的是,我在第一次编辑中发布的次要解决方案并不是一个可行的解决方案,因为它真正报告的只是一个获取失败——与失败的原因无关。这是一些东西,但不是很多。理想情况下,我会设想有一种方法来获取SQL状态代码或其他东西(对于我的错误,可能是以下任何一种:SQL0811,-811,21000,它们在上面的链接中定义)


此外,我不明白为什么SQL错误在php中只被视为E_警告。对我来说似乎有点奇怪,但我在iNavigator中得到了相同的行为(即,只有当您到达受影响的行时,它才会消失),而不是绿色屏幕(它会在查询执行时抛出错误)。因此,这一定与DB驱动程序以及它们如何处理有关。

如果db2\u prepare失败,您是否尝试过使用db2\u stmt\u错误? 然后你可以把它写在日志上

类{
受保护的$errorLog='/tmp/error.log';
保护$Conn;
保护错误;
函数_u构造()
{
$this->Conn=$db2\u connect(您的\u主机、您的\u用户\u您的\u密码);
} 
函数查询($SQL)
{
$this->sql=$sql;
$stmt=db2\u prepare($this->Conn,$this->sql);
如果($stmt)
{
$result=db2_execute($stmt);
while($row=db2\u fetch\u assoc($stmt))
{
$resultSet[]=$row;
}
db2_free_stmt($stmt);
返回$resultSet;
}
其他的
{
$this->err=db2\u stmt\u errormsg();
$this->writeError();
返回null;
}
}
函数writeError()
{
//写入日志

}
如果db2\u prepare失败,您是否尝试过使用db2\u stmt\u错误? 然后你可以把它写在日志上

类{
受保护的$errorLog='/tmp/error.log';
保护$Conn;
保护错误;
函数_u构造()
{
$this->Conn=$db2\u connect(您的\u主机、您的\u用户\u您的\u密码);
} 
函数查询($SQL)
{
$this->sql=$sql;
$stmt=db2\u prepare($this->Conn,$this->sql);
如果($stmt)
{
$result=db2_execute($stmt);
while($row=db2\u fetch\u assoc($stmt))
{
$resultSet[]=$row;
}
db2_free_stmt($stmt);
返回$resultSet;
}
其他的
{
$this->err=db2\u stmt\u errormsg();
$this->writeError();
返回null;
}
}
函数writeError()
{
//写入日志

}
是否有可能显示问题代码?如果没有至少看到失败的代码,很难说。请参阅,搜索“Fetch failure”。仅表示来自SQLFetchScroll()的未成功RC,不一定是SQL错误,可能是连接已断开?…已损坏$stmt?…在循环中的其他API中使用了$stmt?如果没有看到成功获取之后和失败获取之前运行的所有代码,很难猜测。我理解我碰巧获得的错误,并可以更正它,这是“选择多行的结果”错误。就是这个错误让我