******* 存取步驟與常用功能介紹 *******

  1. 先確定系統是否已安裝資料庫對應的函式庫(Unix 為 .so 檔,Windows 為 .dll 檔),
    例如 mysql 為 php_mysqli_libmysql.sophp_mysqli_libmysql.dll 檔,
    (或者舊的 php_mysql_libmysql.sophp_mysql_libmysql.dll)
    PostgreSQL 為 php_pgsql.sophp_pgsql.dll
    這些函式庫位於 php.ini 裡面所設定的 extension_dir 目錄內;
    另外也要將 php.ini 內要使用資料庫函式的 extension 部份的註解取消,
    也就是將 ;extension=php_*.so 左邊的分號(;)拿掉
    如果是在已啟動 Apache 的狀態下更動 php.ini 檔,記得重新啟動 Apache 才會作用。
  2. 設定連結資料庫所必要的資訊,稱為 DSN(Data Source Name),
    DSN 格式類似 FTP,為 <協定>://<使用者>:<密碼>@<主機>/<資料庫名稱>
    然後傳入 MDB2::connect(),以一個變數(Java 稱 Connection 物件)接收,
    以後使用 conn 來建立 PreparedStatement 或 ResultSet 物件
  3. 當 connection 或 statement 或 resultset 物件建立之後,
    可以馬上當引數傳入 PEAR::isError() 來檢查是否建立時有問題
  4. 資料庫處理時可以包在 try 中,發生問題時可以丟給 catch 處理(或更細部處理)
    catch(Exception $e){}的處理部份,可以呼叫 Exception 物件的 method 如下:

    getCode() 列出錯誤代碼
    getMessage() 列出錯誤訊息
    getLine() 列出錯誤行號
    getFile() 列出錯誤檔案
  5. 要執行 SQL 指令有三種方式:
    $conn->exec()$conn->query()$conn->prepare()
    若要快速執行 SQL 指令,可以呼叫 $conn->exec(SQL)。會傳回執行成功的筆數
    如果 INSERT,通常筆數是 1,若 DELETE 或 UPDATE 或 SELECT,筆數可能更多。
    $conn->exec 較適合用來快速下 INSERT、DELETE、UPDATE 指令(不需回傳資料)。
  6. 若要快速執行 SELECT 的 SQL 指令取出 ResultSet,
    可以呼叫 $conn->query(SQL)
    會傳回 ResultSet 物件,然後再讀出 ResultSet 裡的個別 row 資料。
  7. $conn->prepare(arg1,arg2,arg3) 可用預儲指令執行增刪修查等四種含變數 SQL,

    arg1(String):
    傳入要執行的 SQL 指令(字串),但是可以設定變數,在執行期才決定變數的值,
    變數可以用 :name? 兩種 placeholder 來代表,

    :name 在後面 execute 傳入資料時,要傳入關聯式陣列 array(key=>value,…)
    ? 在後面 execute 傳入資料時,要傳入索引陣列 array(value,value,…)

    arg2(字串 array):
    決定 arg1 中指定變數的資料型態。數值為 integer,字串為 text
    要依變數出現的順序設定成 array,再傳到這個引數中。
    arg3(int 常數):
    決定此 PreparedStatement 要執行的是 INSERT、DELETE、UPDATE 改變型,
    或者是 SELECT 查詢資料的動作。
    若是改變資料,則傳入 MDB2_PREPARE_MANIP ( manipulation ) 常數
    若是查詢資料,則傳入 MDB2_PREPARE_RESULT (resultset) 常數
  8. conn->prepare 得到一個 PreparedStatement 物件,
    用 stat->execute() 執行 SQL 指令,傳入 array 當 execute() 的引數,
    如果是 :name 型態的 placeholder,則傳入 array(key=>value) 類的關聯式陣列
    如果是 ? 型態的 placeholder,則傳入 array(value,value,..) 類的索引式陣列
    關聯式陣列內容可以不照順序,但是索引式陣列必須依照 placeholder 順序放置。

    如果有多項指令要執行,可以將資料放到 array 中(含多項 array 型態內容 的 array),
    然後用 foreach 逐項將每一 array 丟入 stat->execute() 當引數。

  9. 除了用一般的 execute 執行 SQL 指令之外,如果資料量眾多的話,可以透過
    conn->loadModule(“Extended",null,false) 來載入 Extended 模組,
    再呼叫 conn->extended->executeMultiple(PreparedStatement,array的array)
    就會把 array 中的資料自動填入 SQL 中執行,而不用呼叫 foreach 逐項執行。
  10. 關於 conn->prepare() 後執行 stat->execute() 所得到的回傳值,
    如果 prepare 型態是 MDB2_PREPARE_MANIP,則是回傳成功執行的筆數
    如果 prepare 型態是 MDB2_PREPARE_RESULT,則是回傳 SELECT 查詢所得到的 ResultSet
  11. 可以透過 conn->prepare(SQL,TYPE,MDB2_PREPARE_RESULT)
    或 conn->query(SQL)
    取得 ResultSet 物件(執行 SELECT SQL 查詢的結果),
    ResultSet 有幾個常用 method 可用:

    1. getColumnNames() 可以取得本次查詢結果的資料表欄位名稱,
      但是名稱會在 key 的位置,value 會是數值,且從 0 開始
    2. numCols() 可以取得本次查詢結果的欄位數量,JOIN TABLE 時較看得出其用途。
    3. numRows() 可以取得本次查詢結果的資料筆數,可以用來當迴圈次數的依據。
    4. seek(num) 可以測試是否有第 num 筆資料,第一筆為 1
      (seek(0) 會傳回 true)。
      如果有這一筆資料則傳回 true,若無,則會出現錯誤,
      可以將 seek 的結果設定給一變數,然後用 PEAR::isError(var) 處理錯誤。
    5. rowCount() 可以傳回目前 cursor 跑到哪一筆資料上,第一筆為 1。
    6. fetchRow(arg1,arg2) 可以取得第 N 筆資料,引數說明如下:

      arg1:決定取出資料成關聯式陣列($row[“name"])或索引式陣列($row[index]),
      關聯式陣列用 MDB2_FETCHMODE_ASSOC,(association)
      索引式陣列用 MDB2_FETCHMODE_ORDERED,(ordered 為預設)
      arg2:決定取出第 N 筆資料,第一筆為 0,可以隨意跳動取出,
      因此算是 scrollable cursor,不管 Mysql 或 PostgreSQL 都可行。
  12. 當 ResultSet 或 PreparedStatement 使用完畢,可以用 free() 釋放資源;
    當 Connection 使用完畢,可以用 disconnect() 釋放資源。