許多開發者假設 update()、delete() 回傳 true/false 表示成功/失敗,**實際上回傳的是「影響的列數」(integer)**。
| 方法 | 回傳值 | 含義 |
|---|---|---|
insert() | int | 新增的列數 (通常 1);失敗拋例外 |
update() | int | **實際更新的列數**;資料未異動時回傳 0 |
delete() | int | 刪除的列數;不存在時回傳 0 |
<?php
$command = Yii::app()->db->createCommand();
$affected = $command->update('post', ['title' => 'New Title'], 'id=1');
if ($affected > 0) { // ❌ 陷阱:資料相同導致 0 列更新,誤判為失敗
echo '成功';
} else {
echo '失敗'; // 實際上可能「成功執行但無資料異動」
}
?>
<?php
$command = Yii::app()->db->createCommand();
try {
// update/delete 不會因「無列影響」拋例外,只有 SQL 錯誤才拋
$affected = $command->update('post', ['title' => 'New Title'], 'id=1');
// 判斷 SQL 是否執行成功 (無例外即成功)
// 如需知道是否有實際異動,檢查 $affected
if ($affected > 0) {
echo "已更新 {$affected} 筆資料";
} else {
echo "執行成功,但無資料異動 (可能條件不符或資料相同)";
}
} catch (CDbException $e) {
// 真正的失敗:SQL 語法錯誤、連線中斷、外鍵衝突等
error_log("DB Error: " . $e->getMessage());
throw new CHttpException(500, '資料庫操作失敗');
}
?>
若業務需區分「不存在」vs「資料相同」,需先查詢:
<?php
$command = Yii::app()->db->createCommand();
// 1. 先檢查是否存在
$exists = $command->select('1')
->from('post')
->where('id=1')
->queryScalar();
if (!$exists) {
throw new CHttpException(404, '文章不存在');
}
// 2. 檢查是否需更新 (避免不必要寫入)
$current = $command->select('title')
->from('post')
->where('id=1')
->queryScalar();
if ($current === 'New Title') {
return ['changed' => false, 'message' => '資料無變更'];
}
// 3. 執行更新
$affected = $command->update('post', ['title' => 'New Title'], 'id=1');
// $affected 應為 1
return ['changed' => true, 'affected' => $affected];
?>
<?php
$transaction = Yii::app()->db->beginTransaction();
try {
$command = Yii::app()->db->createCommand();
$affected1 = $command->update('order', ['status' => 2], 'id=100');
$affected2 = $command->insert('order_log', [
'order_id' => 100,
'action' => 'confirm',
'created_at' => date('Y-m-d H:i:s'),
]);
// 這裡 $affected1 可能為 0 (狀態已是 2),但不應視為失敗
// 關鍵是 insert 必須成功 (否則拋例外)
$transaction->commit();
return true;
} catch (Exception $e) {
$transaction->rollback();
throw $e;
}
?>
<?php
$command = Yii::app()->db->createCommand();
// INSERT
$command->insert('user', ['name' => 'John', 'email' => 'john@example.com']);
// 回傳: 1 (成功) / 拋例外 (失敗)
// 取得自增 ID: Yii::app()->db->getLastInsertID()
// UPDATE
$command->update('user', ['name' => 'Jane'], 'id=1');
// 回傳: 影響列數 (0 表示無異動)
// DELETE
$command->delete('user', 'id=1');
// 回傳: 刪除列數 (0 表示不存在)
// 批次插入 (Yii 1.1.14+)
$command->batchInsert('user', ['name', 'email'], [
['Alice', 'alice@example.com'],
['Bob', 'bob@example.com'],
]);
// 回傳: 成功插入列數
?>
「無例外即成功」;影響列數僅供業務邏輯參考,非成敗判斷依據。