Clendar
Sun Mon Tue Wed Thu Fri Sat
   1234
567891011
12131415161718
19202122232425
2627282930  
<< September 2010 >>
SERACH
ARCHIVES
CATEGORIES
LINKS
RECENT COMMENTS
RECENT TRACKBACK
OTHERS
SKYPE
ID: skype.jojo.jp
chat call
THANKS



本日:
昨日:


 ▼▲ 作業日報 ▼△
  A rolling stone gathers no moss.
<<前ページ 次ページ>>
【SQLite】PDOStatementは開放しないとだめなこともある
PHPではリソースの開放をセッション終了時に自動でやってくれますが、場合によっては(DBがらみ)だと途中でやらないとだめなこともありますな!という例を見つけたのでメモとして残しておきます。
基本的にはオブジェクトの開放はPHPに任せた方が良いらしいです
●行フェッチを行った場合、その参照したテーブルを更新するようなSQLがある場合同一トランザクション上では下記のようなエラーで停止しました。
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 1 SQL logic error or missing database' in C:¥Inetpub¥(--hoge--)¥index.php:169 Stack trace: #0 C:¥Inetpub¥(--hoge--)¥index.php(169): PDO->query('insert or repla...') #1 {main} thrown in C:¥Inetpub¥(--hoge--)¥index.php on line 169

ソースコード抜粋
  $db->beginTransaction();
  try{
    foreach ($arrsitelist as $k => $v){
      $time_open  = $v[2];
      $time_close = $v[3];
      
      $stmt= $db->prepare("select [登録時刻] from tmp_output where siteid='$k';");
      $stmt->execute();
      $time_cur =$stmt->fetchColumn();
			
      unset($stmt);//or $stmt=null;←-------------------------------------これがないと
      
      //時間を取得する
      if ($time_cur){
        $time_cur = (int)$time_cur/100;
        if ($time_close < $time_cur) {
          //$db->query("delete from tmp_output where siteid='$k';");
          
          $sql1 ="select $selectitem from v_mc ";
          $sql1 .="where (siteid='$k') and ([年] = $y) and ([月] = $m) and ";
          $sql1 .="([日] = $d) and ([登録時刻] <= ".$time_close."00);";
          $db->query('insert or replace into tmp_output '.$sql1);←----ここで落ちます 
        }
        
        echo $res."($time_open-$time_close)";
      } else {
        echo 'xx登録がないxx';
      }

    }
    $db->commit();
  } catch(Excetipn $e){
    $db->rollBack();
  };

これは tmp_output テーブル中の[登録時刻]が、$time_close(閉店時間)よりちいさければテーブル内の それ以前の[登録時刻]の値を入れようとした時のものです。カーソルを作った時点でのtmp_outputテーブルでレコードを挿入(置換)しようと しているので、エラーがでるようです。PDOStatementには開放するためのコマンドがないので、普通にいつ開放すべきかを考えていませんでしたが、 この辺は考慮しておく必要があるかなと思いました。このバグを見つけるまでに半日かかりました


自己れすです: PHPのマニュアルサイトに
PDO::query() を次にコールする前に 結果セット内の全てのデータを取得しない場合、そのコールは失敗します。 PDOStatement::closeCursor() をコールし、 次に PDO::query() をコールする前に PDOStatement オブジェクトに関連付けられたリソースを解放してください。
とありました。(汗
| 開発関連 | 17:19 | comments(1) | trackbacks(0) |
承認待ちのコメントです。
| - | 2007/10/23 6:34 AM |









http://blog.jojo.jp/trackback/385674
<<前ページ 次ページ>>