- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
基本的には
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}}