1

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(): 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句でラップすることです(たとえば、ヘッダーインクルードとフッターインクルードにインクルードします)。これにより、ページの実行が可能になり、ネストされた句が許可されているため、通常どおりに try-catch を使用できます。汚いらしいけど。catchtry{}catch(Exception $exc){}try-catch

EDIT2: 明確にするために、私はどのエラーが発生しているのか、またはそれを修正する方法を理解しようとはしていません-それが何であるか、およびそれを修正する方法はすでに知っています。しかし、記録のために、私が得ているエラーはここSQL0811で定義されているものです。私が理解しようとしているのは、によって生成された E_WARNING を検出して適切に処理する方法です。db2_fetch_assoc(). 理由は、私がそれを検出しない場合、最初の影響を受けたレコードでフェッチ プロセスがプリエンプティブに終了するためですが、ページはすべてが正常であるかのようにレンダリングされるためです。したがって、将来的には、何かが正しく機能していないことに数か月後に気付くのではなく、これらの状況を検出するためのセーフガードを用意したいと考えています. 残念ながら、最初の編集で投稿した小さな解決策は実行可能な解決策ではありません。実際に報告されるのは、フェッチの失敗があったことだけです。その失敗の原因については何も報告されていません。それは何かですが、それほど多くはありません。理想的には、SQL 状態コードなどを取得する方法があると思います (私のエラーの場合、上記のリンクで定義されている SQL0811、-811、21000 のいずれかになります)。

さらに、PHP で SQL エラーが E_WARNING としか見なされない理由がわかりません。私にはちょっと奇妙に思えますが、iNavigator でも同じ動作が得られます (つまり、問題のある行に到達したときにのみ停止します) が、緑色の画面ではありません (代わりに、クエリの実行時にエラーがスローされます)。したがって、DB ドライバーとその処理方法に関係があるはずです。

4

1 に答える 1

0

db2_prepare が失敗した場合、db2_stmt_errors を使用してみましたか? その後、ログに書き出すことができます

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

    }

于 2015-09-21T15:22:26.143 に答える