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

时间:2015-08-07 16:19:34

标签: php error-handling ibm-midrange db2-400 ibm-db2

我在Zend Server 8.0.2上使用PHP 5.6.5,ibm_db2驱动程序使用DB2 for IBM i(iSeries(AS / 400))。

我遇到了一个实例,其中包含名称别名的子选项的视图可能会也可能不会返回多行。我没有创建视图,我理解错误并且可以纠正它。奇怪的是,在PHP中,不会在db2_exec()上抛出错误,而是在db2_fetch_assoc()上抛出错误。我开始研究它,我找不到一种方法来优雅地检测db2_fetch_assoc()生成的错误。它在Zend错误日志中记录为" db2_fetch_assoc():获取失败",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: How to manage errors gracefully? 这个答案描述了如何在发生警告时强制执行异常(这是我从db2_fetch_assoc()获得的)。缺点是如果没有捕获,任何警告都会导致页面执行停止。

我很有趣的想法是将我的整个页面包含在try-catch条款中,其中catch不执行任何操作(例如包括try{在标题中包含和页脚中的}catch(Exception $exc){}包括)。这将允许页面执行,并且由于允许嵌套的try-catch子句,我仍然可以使用try-catch,就像我通常那样。虽然看起来很脏。

EDIT2: 只是为了澄清,我不是要弄清楚我得到的错误或如何纠正它 - 我已经知道它是什么以及如何纠正它。但是对于记录,我得到的错误是SQL0811,其定义为here。我想弄清楚的是如何检测并优雅地处理由db2_fetch_assoc()生成的E_WARNING。理由是因为如果我没有检测到它,那么获取过程将抢先结束第一个受折磨的记录,但页面将呈现为好像一切都很好。因此,对于未来,我希望有一个安全措施,可以检测到这些情况,而不是意识到几个月没有正常工作。不幸的是,我在第一次编辑中发布的次要解决方案并不是一个可行的解决方案,因为它真正报告的是提取失败 - 没有关于失败的原因。它是一些东西,但并不多。理想情况下,我认为有一种方法可以获取SQL状态代码或其他东西(对于我的错误,它将是以下任何一种:SQL0811,-811,21000,它们在上面的链接中定义)。

此外,我无法弄清楚为什么SQL错误在php中仅被视为E_WARNING。对我来说似乎有些奇怪,但是我在iNavigator中得到了相同的行为(即,只有当你到达一个受影响的行时才会死掉)但不是绿色屏幕(这会在查询执行时抛出错误)。所以它必须与数据库驱动程序及其处理方式有关。

1 个答案:

答案 0 :(得分:0)

如果db2_prepare失败,您是否尝试过使用db2_stmt_errors? 然后你可以把它写到日志

&#13;
&#13;
class ISeriesDB2 {

   protected $errorLog = '/tmp/error.log';
   protected $Conn;
   protected err;

   function __construct()
   {

       $this->Conn = $db2_connect(YOUR_HOST,YOUR_USER_YOUR_PASSWD);

   } 


  function query($SQL)

  {



		$this->sql = $SQL;
 
		 
		
		$stmt = db2_prepare($this->Conn, $this->sql);



        if ($stmt)
		{

			
			$result = db2_execute($stmt);
			

			while ($row = db2_fetch_assoc($stmt))
		   {
			 
			
				$resultSet[] = $row;
		   }


			db2_free_stmt($stmt);	
			return $resultSet;
		}
		else
		{
			
			$this->err = db2_stmt_errormsg();


			$this->writeError();

			return null;
		}
           
		
 



   }

   function writeError()
    {
       // write to the log

    }
&#13;
&#13;
&#13;