### SQL 基礎查詢
#### SELECT 查詢
*查詢返回多行:*
$command = $connection->createCommand('SELECT * FROM post');
$posts = $command->queryAll();
返回單行:
$command = $connection->createCommand('SELECT * FROM post WHERE id=1');
$post = $command->queryOne();
查詢多行單值:
$command = $connection->createCommand('SELECT title FROM post');
$titles = $command->queryColumn();
查詢標量值/計算值:
$command = $connection->createCommand('SELECT COUNT(*) FROM post');
$postCount = $command->queryScalar();
#### UPDATE, INSERT, DELETE 更新、插入和刪除等
如果執行 SQL 不返回任何數據可使用命令中的 execute 方法:
$command = $connection->createCommand('UPDATE post SET status=1 WHERE id=1');
$command->execute();
你可以使用insert,update,delete 方法,這些方法會根據參數生成合適的SQL并執行.
// INSERT
$connection->createCommand()->insert('user', [
'name' => 'Sam',
'age' => 30,
])->execute();
// INSERT 一次插入多行
$connection->createCommand()->batchInsert('user', ['name', 'age'], [
['Tom', 30],
['Jane', 20],
['Linda', 25],
])->execute();
// UPDATE
$connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();
// DELETE
$connection->createCommand()->delete('user', 'status = 0')->execute();
`引用的表名和列名
`
大多數時間都使用以下語法來安全地引用表名和列名:
$sql = "SELECT COUNT($column) FROM {{table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();
以上代碼$column 會轉變為引用恰當的列名,而{{table}} 就轉變為引用恰當的表名。 表名有個特殊的變量 {{%Y}} ,如果設置了表前綴使用該變體可以自動在表名前添加前綴:
$sql = "SELECT COUNT($column) FROM {{%$table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();
*預處理語句
*
為安全傳遞查詢參數可以使用預處理語句,首先應當使用:placeholder占位,再將變量綁定到對應占位符:
$command = $connection->createCommand('SELECT * FROM post WHERE id=:id');
$command->bindValue(':id', $_GET['id']);
$post = $command->query();
另一種用法是準備一次預處理語句而執行多次查詢:
$command = $connection->createCommand('DELETE FROM post WHERE id=:id');
$command->bindParam(':id', $id);
$id = 1;
$command->execute();
$id = 2;
$command->execute();
提示,在執行前綁定變量,然后在每個執行中改變變量的值(一般用在循環中)比較高效.
#### 事務
當你需要順序執行多個相關的的query時,你可以把他們封裝到一個事務中去保護數據一致性.Yii提供了一個簡單的接口來實現事務操作. 如下執行 SQL 事務查詢語句:
$transaction = $connection->beginTransaction();
try {
$connection->createCommand($sql1)->execute();
$connection->createCommand($sql2)->execute();
// ... 執行其他 SQL 語句 ...
$transaction->commit();
} catch(Exception $e) {
$transaction->rollBack();
}
我們通過yii\db\Connection::beginTransaction()開始一個事務,通過try catch 捕獲異常.當執行成功,通過yii\db\Transaction::commit()提交事務并結束,當發生異常失敗通過yii\db\Transaction::rollBack()進行事務回滾.
如需要也可以嵌套多個事務:
// 外部事務
$transaction1 = $connection->beginTransaction();
try {
$connection->createCommand($sql1)->execute();
// 內部事務
$transaction2 = $connection->beginTransaction();
try {
$connection->createCommand($sql2)->execute();
$transaction2->commit();
} catch (Exception $e) {
$transaction2->rollBack();
}
$transaction1->commit();
} catch (Exception $e) {
$transaction1->rollBack();
}