此文分為兩個單元
1 Select 的使用
2 builder class/Insert/Update,Delete和其他的使用。
測試的資料庫結構
本文的範例全部採用這個表格 `TW_city`
啟動資料庫查詢
修改 vi config/autoload.php
建立查詢
這是建立查詢的基本步驟
$sql = "SELECT * FROM TW_city"; //這是SQL語法
$q = $this->db->query( $sql );
這個步驟會建立mysql_query的物件,如果是Select的話再利用這個物件的方法叫回資料;如果是其他的方法如insert/update/delete則就會直接執行語法,並回傳true(達行成功)/ false(執行失敗)。
所以說,這個 $q 就是建立查詢完畢後的mysql物件。
取得一行
1. 取得一行物件資料,這裡取得的是物件
$obj = $q->row();
印出其中一欄
print $obj->city; //台北市
若印出的物件不存在,會出現未定義物件的錯誤:
print $obj->test;
出現錯誤
Notice: Undefined property: stdClass::$test
2. 取得一行陣列資料,這裡取得的是陣列
$r = $q->row_array();
印出其中一欄
print $r['city']; //台北市
若印出的陣列索引不存在,會出現未定義索引的錯誤:
print $r['test'];
出現錯誤
Notice: Undefined index: test
3. 取得指定行--陣列用法
$r = $q->row_array(3); //索引3,由0請算代表第4個
// 印出其中一欄
print $r['city']; //高雄市
// 取得下一列
$r = $q->next_row('array');
print $r['city']; //台南市
// 取得不存在的索引
$r = $q->row_array(30); //索引30,不存在,結果等於第一行:台北市
$r = $q->row_array(-1); //索引-1 不存在,結果等於第一行:台北市
4. 取得指定行--物件用法
$obj = $q->row(0); //索引0,由0請算代表第1個
print $obj->city; //台北市
// 取得上一列
$obj = $q->previous_row();
print $obj->city; //台北市,到最上面,所以第0行的上一行還是第0行
$obj = $q->row(300); //索引不存在
print $obj->city; // 台北市
$obj = $q->row(-1); //索引不存在
print $obj->city; // 台北市
5. 如果本身就無資料
$sql = "SELECT * FROM TW_city where citycode>10"; //這個SQL查詢不到任何資料
$q = $this->db->query( $sql );
$obj = $q->row(); //NULL
print $obj->city; // 出現 Trying to get property of non-object 這個錯誤
$r = $q->row_array(); // NULL
print $r['city']; // 完全空白
取得一行小結
1. 建議使用陣列寫法,即 row_array()。
2. 無論你的SQL查詢出幾行,都只會取出第一行。
3. 如果本身SQL查詢出的資料就是空的,查詢的結果就會是 NULL,用物件的寫法會出現錯誤,用陣列的寫法會是空白。
4. 判斷查詢是否有結果,可以用 下面兩個方法:
if ($q->num_rows() > 0){ ... }
if ($q->row_array() ){ ... }
5. 儘量不要指定索引位置,它會讓你搞不清楚你現在到底取第幾行,如果想指定位置,請用SQL來指定。
$r = $q->row_array(); 建議
$r = $q->row_array(3); 不建議指定
6. 儘量不要用這些函數,它們會讓你搞不清楚東西南北
$row = $q->first_row()
$row = $q->last_row()
$row = $q->next_row()
$row = $q->previous_row()
7. 請在SQL上設定 limit 1,在查詢時就只取一行
取得一個值
有時我們只要取得一個欄位,可使用下面這個方法取出其中的一欄
$r = $q->row_array();
印出其中一欄
print $r['city']; //台北市
但是有時候我們在查詢時只有一個欄位,可以用下面的寫法來取那唯一的一欄,例如:
$sql ="SELECT count(city) FROM TW_city";
$q = $this->db->query( $sql);
$r=$q->row_array();
print array_shift($r); //就是我們要的那一欄
這樣有一個缺點,如果查詢不到任何資料,會出現 array_shift() expects parameter 1 to be array, null given 錯誤
取得全部
1. 取得全部的物件寫法
foreach ($q->result() as $row)
{
echo $row->city;
echo $row->alias;
echo $row->read;
}
2. 取得全部的陣列寫法
foreach ($q->result_array() as $r)
{
echo $r['city'];
echo $r['alias'];
echo $r['read'];
}
取得全部小結
1. $q->result() 代表著全部資料的物件;$q->result_array() 代表著全部資料的陣列;
2. 建議使用陣列寫法
unbuffered_row 和 row 的主要差異
前面使用的 row() ,row_array(), result(), result_array() 的方法都是先將資料庫查詢的結果放到記憶體中,然後再取出,這樣的優點是對資料庫的存取少,速度快,缺點是耗損記憶體空間。
使用 unbuffered_row 這個方法就能避免這個困難,他是循序讀取資料後,指標會指到下一筆資料,直到回傳null為止(結束),所以對資料庫的存取就會多,但不太佔用記憶體。
所以如果大資料(例如50行以上大量數據),請使用unbuffered_row的方法來取代 row。
使用 while
在while 中只能用unbuffered_row 這個方法,因為他回傳資料後,指標會指到下一筆資料,直到回傳null為止(結束),請勿在while中使用row()方法,會變成無窮迴圈。
1. 物件方法
while($r= $q->unbuffered_row()){
print $r->city;
}
2. 陣列方法
while($r= $q->unbuffered_row('array')){
print $r['city'];
}
使用while如果資料是空值null,大括號裡的部分不會被執行
使用輔助函數
1. num_rows()
取回資料庫查詢出來的行數。
$q = $this->db->query( $sql);
print $q->num_rows();
2.num_fields()
取回資料庫查詢出來每行的欄數。
$q = $this->db->query( $sql);
print $q->num_fields();
3. free_result()
清空查詢所有的結果,也就是這個 $q 會變成空物件。原則上在php執行到最後自動會清除掉所有的變數,但是如果執行過程中要多次存取大資料,可以手動清除。
print $q->num_fields(); //4
$q->free_result();
print $q->num_fields(); // 出錯 Trying to get property of non-object,因為$q已經是空物件
4. data_seek(n)
跳過前面的 n筆資料
$q->data_seek(3); // 跳過前面的 3筆資料
while($r= $q->unbuffered_row('array')){
print $r['city']; // 從高雄市開始印
}
如果使用2次以上,並不會影響結果
$q->data_seek(3); // 跳過前面的 3筆資料
$r = $q->row_array();
print $r['city']; //高雄市
$q->data_seek(3); // 跳過前面的 3筆資料
$r = $q->row_array();
print $r['city']; //結果還是高雄市,指標還是在0的位置
5. list_fields()
傳回欄位名稱的陣列
整理的函數
我整理上面的結果,寫了幾個函數
/**** 資料庫用 ***/ // 傳回全部陣列,無資料回傳NULL public function getAll($query){ return $query->result_array(); } // 傳回一整欄單一陣列,無資料回傳NULL // @param $item: 欄位名 public function getCol($query, $item=""){ $all=$query->result_array(); $col=array(); foreach($all as $it){ if($item && $it[$item])$col[]=$it[$item]; if(!$item)$col[]=array_shift($it); } return $col; } // 傳回一個值,無資料回傳 false; public function getOne($query){ $row=$query->row_array(); if($row) return array_shift($row); return false; } //傳回一整行,無資料回傳NULL public function getRow($query){ return $query->row_array(); }
參考資料
[1] CI3 DATABASE官網文件 http://www.codeigniter.com/userguide3/database/index.html