トップ 一覧 置換 検索 ヘルプ RSS ログイン

MDB2で、PLSQLを実行するの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
基本的には
 begin test_p('test1', 'test2'); end;
をで良い。しかし、 output を引数に取るプロシージャの場合はちょっと問題。

そこで、MDB2.php と oci8.php に修正を加える

MDB2.php
  *** MDB2_20111021.php   Fri Oct 21 00:37:37 2011
  --- MDB2.php    Fri Oct 21 00:41:34 2011
  ***************
  *** 3875,3880 ****
  --- 3875,3881 ----
        var $result_types;
        var $types;
        var $values = array();
  +     var $result = array();
        var $limit;
        var $offset;
        var $is_manip;
  ***************
  *** 4063,4068 ****
  --- 4064,4070 ----
                }
            }
            $result =& $this->_execute($result_class, $result_wrap_class);
  +         $values = $this->result;
            return $result;
        }
  
  ***************
  *** 4141,4146 ****
  --- 4143,4149 ----
            $this->is_manip = null;
            $this->offset = null;
            $this->values = null;
  +         $this->result = null;
  
            return MDB2_OK;
        }

Driver/oci8.php
  *** oci8_20111021.php   Fri Oct 21 00:39:25 2011
  --- oci8.php    Fri Oct 21 00:39:59 2011
  ***************
  *** 1415,1420 ****
  --- 1415,1421 ----
                    }
                } else {
                    $quoted_values[$i] = $this->db->quote($value, $type, false);
  +                 $quoted_values[":$parameter"] = &$quoted_values[$i];
                    if (PEAR::isError($quoted_values[$i])) {
                        return $quoted_values[$i];
                    }
  ***************
  *** 1482,1487 ****
  --- 1483,1489 ----
            $result =& $this->db->_wrapResult($this->statement, $this->result_types,
            $result_class, $result_wrap_class, $this->limit, $this->offset);
            $this->db->debug($this->query, 'execute', array('is_manip' => $this->is_manip, 'when' => 'post', 'result' => $result));
  +         $this->result = $quoted_values;
            return $result;
        }


これで、
 $stmt = $this->db->prepare($sql, $types);
 $result = $stmt->execute(&$args);
とすると、output の結果が、$args に入ってくるはず。
または、
 $result = $stmt->execute($args);
 print_r($stmt->result);
でもいいかな。

簡単なDBアクセスクラスを作って置くと良い。
{{code Java,
<?php
  /**
  * データベースアクセスクラス
  *
  * データベースの読書きの機能を提供する。
  * インスタンスは getInstance() で取得する。
  * 
  * SQLiteは、version2
  **/
  
  require_once 'MDB2.php';
  
  // common.php に定義されている場合は無視される
  define ("_dns","sqlite:///test.db2");
  
  class DBAccess {
    /**定数*/
    const ALL = 1;
    const ONE = 2;
    const ST = 3;
    
    /** データベースインスタンス */
    var $db = null;
    /** DBAccess インスタンス */
    static $objSelf = null;
    
    /** DBAccess インスタンス取得 */
    public static function &getInstance(){
      if (!isset(self::$objSelf)){
        self::$objSelf = new DBAccess();
      }
      return self::$objSelf;
    }
    
    
    /**
    * 接続されているかをチェックする。
    * 接続されている場合はTrue。
    */
    public function isConnect(){
      return isset($this->db);
    }
    
    
    /**
    * データベースに接続する。
    */
    public function connect($strcon = _dns ){
      $res = false;
      if (!$this->isConnect()){
        $options['persistent'] = false;
        $this->db = MDB2::factory( _dns,$options );
        if (PEAR::isError($this->db)){
          $ex = new DBAccessException("DB接続エラー : " . $this->db->getMessage());
          unset($this->db);
          throw $ex;
          $res = false;
        } else {
          $this->db->loadModule('Extended');
          $this->db->loadModule('Function');
          $this->db->setOption('field_case', CASE_UPPER);
          $this->db->setOption('portability',
            MDB2_PORTABILITY_FIX_CASE | MDB2_PORTABILITY_RTRIM);
          $res = true;
        }
      } else {
        $res = true;
      }
      return $res;
    }
    
    
    /** データベースから切断する。 */
    public function disconnect(){
      if ($this->isConnect()){
        $ret = $this->db->disconnect();
        if ($ret){
          unset($this->db);
        } else {
          $ex = new DBAccessException("DB切断エラー : " . $ret->getMessage());
          unset($this->db);
          throw $ex;
        }
        return $ret;
      } else {
        return true;
      }
    }
    
    
    // public function &executeStoredProc($sql, $args = array(), $fetchmode = DBAccess::ALL, $mode = MDB2_FETCHMODE_ASSOC){
    // $this->connect();
    // $st = $this->db->executeStoredProc($sql, $args);
    // 
    // if (PEAR::isError($st)){
    // throw new DBAccessException("DB実行エラー : " . $st->getMessage(). " : ". $st .": ".$st->getDebugInfo() );
    // }
    // 
    // if ($fetchmode == DBAccess::ALL){
    // $ret = $st->fetchAll($mode);
    // $st->free();
    // $st = null;
    // } else if ($fetchmode == DBAccess::ONE){
    // $ret = $st->fetchRow($mode);
    // $st->free();
    // $st = null;
    // } else if ($fetchmode == DBAccess::ST){
    // $ret = $st;
    // }
    // return $ret;
    // }
    
    // public function &executeDatabaseProc($name, $args = array(), $fetchmode = DBAccess::ALL, $mode = MDB2_FETCHMODE_ASSOC){
      // 
      // $query = "BEGIN ".$name;
      // $query .= $args ?
      // "('".implode("', '", $args)."')" : "()";
      // $query .= ";end;";
      // 
      // echo $query;
      // $this->connect();
      // $st = $this->db->query($query, null, true, false);
      // if (PEAR::isError($st)){
        // throw new DBAccessException("DB実行エラー : " . $st->getMessage(). " : ". $st .": ".$st->getDebugInfo() );
      // }
      // 
      // if ($fetchmode == DBAccess::ALL){
        // $ret = $st->fetchAll($mode);
        // $st->free();
        // $st = null;
      // } else if ($fetchmode == DBAccess::ONE){
        // $ret = $st->fetchRow($mode);
        // $st->free();
        // $st = null;
      // } else if ($fetchmode == DBAccess::ST){
        // $ret = $st;
      // }
      // return $ret;
    // }
    
    public function &exec($sql, $fetchmode = DBAccess::ALL, $mode = MDB2_FETCHMODE_ASSOC){
      $this->connect();
      $st = $this->db->query($sql);
      
      if (PEAR::isError($st)){
        throw new DBAccessException("DB実行エラー : " . $st->getMessage() . " : ". $sql .": ");
      }
      
      if ($fetchmode == DBAccess::ALL){
        $ret = $st->fetchAll($mode);
        $st->free();
        $st = null;
      } else if ($fetchmode == DBAccess::ONE){
        $ret = $st->fetchRow($mode);
        $st->free();
        $st = null;
      } else if ($fetchmode == DBAccess::ST){
        $ret = $st;
      }
      return $ret;
    }
    
    public function execSql($sql){
      $this->connect();
      $ret = $this->db->exec($sql);
      if (PEAR::isError($ret)){
        throw new DBAccessException("DB実行エラー : " . $ret->getMessage(). " : ". $sql .": ");
      }
      return $ret;
    }
    
    /**
    *  準備された SQL 文を実行する
    * @access    public
    * @param     Statement    $stmt プリペアドステートメント
    * @param     array     $params プリペアドステートメントの実行時に使用される配列。 
    * @param     mixed     query の実行結果
    */
    public function &execSt($stmt, $args = array(), $fetchmode = DBAccess::ALL, $mode = MDB2_FETCHMODE_ASSOC){
      $st = $stmt->execute(&$args);
      if (PEAR::isError($st)){
        // throw new DBAccessException("DB実行エラー : " . $st->getMessage(). " : ". $st .": ");
        throw new DBAccessException("DB実行エラー : " . $st->getMessage(). " : ". $st .": ".$st->getDebugInfo() );
      }
      
      if ($fetchmode == DBAccess::ALL){
        $ret = $st->fetchAll($mode);
      } else if ($fetchmode == DBAccess::ONE){
        $ret = $st->fetchRow($mode);
      } else if ($fetchmode == DBAccess::ST){
        $ret = $st;
      }
      return $ret;
    }
    
    
    /**
    *  後で実行するための SQL 文を準備する
    * @access    public
    * @param     String    $sql クエリのハンドル、あるいは失敗した場合に DB_Error オブジェクトを返します。 
    */
    public function &prepare($sql, $types = array()){
      $this->connect();
      $st = $this->db->prepare($sql, $types);
      if (PEAR::isError($st)){
        throw new DBAccessException("DB実行エラー : " . $st->getMessage(). " : ". $sql .": ");
      }
      return $st;
    }
    
    // /** 行列入れ替え
    // Oracleから移行時にOracleのライブラリにあわせるため */
    // function reverse($data){
      // if (count($data) < 1){
        // return $data;
      // }
      // $row = count($data);
      // $keys = array_keys($data[0]);
      // $keycnt = count($keys);
      // $newdata = array();
      // $newkeyname = "";
      // 
      // for ($r = 0; $r < $row; $r++){
        // for ($k = 0; $k < $keycnt; $k++){
          // $newkeyname = mb_convert_encoding($keys[$k],'SJIS','UTF-8');
          // $newdata[$newkeyname][$r] = mb_convert_encoding( $data[$r][$keys[$k]], 'SJIS', 'UTF-8' );
        // }
      // }
      // return $newdata;
    // }
    
    public function beginTransaction(){
      $this->connect();
      return $this->db->beginTransaction();
    }
    
    public function commit(){
      $this->db->commit();
    }
    
    public function rollBack(){
      $this->db->rollBack();
    }
    
  }
  class DBAccessException extends Exception {
    
  }
  
?>
}}
※PHPの場合、毎回プロセスが上がるので getInstance してもその都度オブジェクトが生成されるはず。なので1つのセッションを使いまわすことにはならない。
{{category2 プログラミング言語,PHP}}