******* 簡易程式範例 *******

本程式動作順序:

  1. 新增兩個 TABLE 的資料
  2. 從 TABLE 取出資料後列出
  3. 刪除兩個 TABLE 的所有資料

若要讓此程式可以正常運作,必須先建立資料庫以及相關資料表,
資料表可以如以下的方式建立:
(mysql 與 pgsql 皆同,差異在 pgsql 不能用 user 當 column 名稱)

CREATE TABLE users(room VARCHAR(8) NOT NULL,user_id VARCHAR(10) NOT NULL);
CREATE TABLE list(user_id VARCHAR(10) NOT NULL,block VARCHAR(10) NOT NULL);

db.inc 內容如下:

define(“RDBMS","資料庫種類"); // 例如 mysql 或 pgsql
define(“USER","資料庫使用者名稱");
define(“PASS","資料庫使用者密碼");
define(“HOST","資料庫所在主機"); // 例如 localhost
define(“DBNAME","資料庫名稱");

程式本體:


require_once "MDB2.php";
require "db.inc";
  
$dsn=RDBMS."://".USER.":".PASS."@".HOST."/".DBNAME;

try
{
  # 依據 DSN 設定建立資料庫連線
  $conn=MDB2::connect($dsn);
  if(PEAR::isError($conn))
    throw new Exception($conn->getMessage());

#***************************************************
# 1.建立 users 資料表的資料,分成兩部份,(1)room RBS 的使用者資料
# 第一次使用 $conn->loadModule("Extended",null,false) 一次將整個陣列寫入

  $datatype=array("text","text");
  $ins_users=$conn->prepare("INSERT INTO users VALUES(:room,:user_id)",$datatype,MDB2_PREPARE_MANIP);
  if(PEAR::isError($ins_users))
    throw new Exception($ins_users->getMessage());

  $users_RBS=array(array("room"=>"RBS","user_id"=>"Terry"),
                   array("user_id"=>"Andy","room"=>"RBS"),
                   array("room"=>"RBS","user_id"=>"Joe"),
                   array("user_id"=>"Mai","room"=>"RBS"),
                   array("room"=>"RBS","user_id"=>"Mary"));
  $conn->loadModule("Extended",null,false);
  $conn->extended->executeMultiple($ins_users,$users_RBS);

#**************************************************
# (2)建立 list Mai 的黑名單
# 第二次使用 ? placeholder 以及 loadModule - Extended 的方式建立
  $ins_list=$conn->prepare("INSERT INTO list VALUES(?,?)",$datatype,MDB2_PREPARE_MANIP);
  if(PEAR::isError($ins_list))
    throw new Exception($ins_list->getMessage());

  $list_Mai=array(array("Mai","Terry"),array("Mai","Joe"));
  $conn->extended->executeMultiple($ins_list,$list_Mai);

#**************************************************
# (3)建立 room RB2 的使用者資料
# 第三次使用 array 的 foreach 一筆一筆依據 array 資料寫入(同 PDO 作法)
  $users_RB2=array(array("room"=>"RB2","user_id"=>"XiangFei"),
                   array("user_id"=>"Rick","room"=>"RB2"),
                   array("room"=>"RB2","user_id"=>"Alex"));
  foreach($users_RB2 as $rb2)
  { $ins_users->execute($rb2); }

#**************************************************
# (4)建立 list Mary 的黑名單
# 第四種使用 ? placeholder 以及 foreach 依據 array 資料筆數寫入
  $list_Mary=array(array("Mary","Andy"),array("Mary","Joe"));
  foreach($list_Mary as $mary)
  { $ins_list->execute($mary); }

#**************************************************
# 不再使用 statement 則將 statement 釋放
  $ins_users->free();
  $ins_list->free();

#**************************************************
# 2.取出資料表的資料列出來
# (1)使用 fetchRow 一筆一筆取出,並顯示目前 cursor 到哪一筆(最後一筆)
  $query=$conn->prepare("SELECT * FROM users WHERE room = :room AND user_id NOT IN (SELECT user_id FROM list WHERE block = :block)",$datatype,MDB2_PREPARE_RESULT);
  if(PEAR::isError($query))
    throw new Exception($query->getMessage());

  $res=$query->execute(array("room"=>"RBS","block"=>"Joe"));
  if(PEAR::isError($res))
    throw new Exception($res->getMessage());

  # 列出所有欄數、列數及標題名稱
  $num_cols=$res->numCols();	// 求出共有幾欄
  $num_rows=$res->numRows();	// 求出共有幾筆記錄
  print "<h3>本記錄共有 {$num_cols} 個欄位,{$num_rows} 筆記錄</h3>";

# getColumnNames() 會將 column name 放到 array 的 key 位置,value 則是 0 開始的數字
  $col_names=array_keys($res->getColumnNames());

# 先列出資料表欄位的名稱,再將記錄一筆一筆列出
# 使用 fetchRow 取出資料,index 從 0 開始
  print "<table border='1'><tr>";
  foreach($col_names as $col)
  { print "<th>{$col}</th>"; }
  print "</tr>";

  foreach(range(0,$num_rows-1) as $num)
  {
    $row=$res->fetchRow(MDB2_FETCHMODE_ASSOC,$num);
    print "<tr><td>{$row['room']}</td><td>{$row['user_id']}</td></tr>";
  }

  print "</table><p />";
  # 列出目前 cursor 在哪一筆的位置上,第一筆為 1
  print "目前 cursor 位置在:第 ".$res->rowCount()." 號位置<p />";

  # 使用 seek 查詢是否有第 N 筆記錄,第一筆為 1,但是 seek(0) 回傳 true
  # 有的話會回傳 true,沒有的話會出現錯誤,可由 PEAR::isError 判斷
  $row=$res->seek(0);
  if(PEAR::isError($row))
    throw new Exception($row->getMessage());

  print "seek(0) 的結果是: {$row}<p />";

#***************************************************
# (2)使用 fetchRow 跳著取出資料,測試 scrollable cursor 是否可行
# 實驗結果→PEAR::MDB2 支援 mysql 及 pgsql 的 scrollable cursor
  $row=$res->fetchRow(MDB2_FETCHMODE_ASSOC,2);
  print "第 3 筆為 {$row['room']} → {$row['user_id']} <p/>";
  $row=$res->fetchRow(MDB2_FETCHMODE_ORDERED,0);
  print "第 1 筆為 {$row[0]} → {$row[1]} <p />";

#***************************************************
# (3)使用 conn->query() 快速取出 SELECT 的資料
  $res=$conn->query("SELECT * FROM list");
  $num_rows=$res->numRows();
  $col_names=array_keys($res->getColumnNames());

# 先列出資料表欄位的名稱,再將記錄一筆一筆列出
# 使用 fetchRow 取出資料,index 從 0 開始
  print "<table border='1'><tr>";
  foreach($col_names as $col)
  { print "<th>{$col}</th>"; }
  print "</tr>";

  foreach(range(0,$num_rows-1) as $num)
  {
    $row=$res->fetchRow(MDB2_FETCHMODE_ORDERED,$num);
    print "<tr><td>{$row[0]}</td><td>{$row[1]}</td></tr>";
  }

  print "</table><p />";
  # 列出目前 cursor 在哪一筆的位置上,第一筆為 1
  print "目前 cursor 位置在:第 ".$res->rowCount()." 號位置<p />";

  # 不再使用 resultset 則將 resultset 釋放
  $res->free();

#**************************************************
# 3.清空資料表內的所有資料
# (1)使用 :name 型態的 placeholder 刪除 RBS 房間的使用者
  el_users=$conn->prepare("DELETE FROM users WHERE room = :room",$datatype,MDB2_PREPARE_MANIP);
  $count=$del_users->execute(array("room"=>"RBS"));
  print "<h3>共刪除了 {$count} 筆房間為 RBS 的使用者</h3>";

#**************************************************
# (2)使用 :name 型態的 placeholder 刪除 RB2 房間的使用者
  $count=$del_users->execute(array("room"=>"RB2"));
  print "<h3>共刪除了 {$count} 筆房間為 RB2 的使用者</h3>";

#**************************************************
# (3)使用 ? 型態的 placeholder 刪除 Mai 的黑名單
  $del_list=$conn->prepare("DELETE FROM list WHERE user_id = ?",$datatype,MDB2_PREPARE_MANIP);
  $count=$del_list->execute(array("Mai"));	
  print "<h3>共刪除了 {$count} 筆使用者 Mai 的黑名單</h3>";
	
#**************************************************
# (4)使用 ? 型態的 placeholder 刪除 Mary 的黑名單
  $count=$del_list->execute(array("Mary"));	
  print "<h3>共刪除了 {$count} 筆使用者 Mary 的黑名單</h3>";

#**************************************************
# 不再使用 statement 及 connection 則將它們釋放
  $del_users->free();
  $del_list->free();

  $conn->disconnect();
}
catch(Exception $x)
{
  exit("錯誤代碼:".$x->getCode()."<br />".
       "錯誤訊息:".$x->getMessage()."<br />".
       "錯誤行數:".$x->getLine()."<br />".
       "錯誤檔案:".$x->getFile()."<br />");
}