0%

数据库大作业笔记(六)

PHP调用mysql存储过程

请忽略我在第五篇笔记里的胡言乱语,现在的存储过程正常啦 哈哈哈

MySQL里的存储过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_update`(IN `newcatid` CHAR(2), IN `newprice` FLOAT)
DETERMINISTIC
BEGIN
IF(select count(*) from borrow,equipment,category
where borrow.eqpid=equipment.eqpid and equipment.catid=category.catid and category.catid=newcatid group by category.catid
)<5
THEN
UPDATE category set price=newprice where catid=newcatid;
ELSE
UPDATE category set price=(newprice*0.9) where catid=newcatid;
end if;
select newcatid,newprice;
END$$
DELIMITER ;

这是一个在更新时调用的存储过程,PHP里想调用存储过程,要改写控制器里的actionUpdate()函数:

Path: backend\controllers\CategoryController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {

$command= Yii::$app->db
->createCommand('call proc_update(:p0,:p1)')
->bindValues([":p0" =>$model->catid, ":p1" =>$model->price]);
$res=$command->execute();
if($res>=0)
{
return $this->redirect(['view', 'id' => $model->catid]);
}
}
return $this->render('update', [
'model' => $model,
]);
}

另外哈,createCommand()里的sql语句出问题的话,要学会解决呀~~比如去掉某一个空格,故意让这个句子出错,然后去看报错信息里的sql语句有什么问题,为什么在MySQL里不起作用。

yii框架中的数据库访问对象

连接数据库

首先要创建数据库连接,语法很好查到。因为数据库连接经常使用,所以在一开始就一应用组件的方式来配置它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
return [
// ...
'components' => [
// ...
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=example',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
// ...
];

之后就可以通过语句 Yii::$app->db 来使用数据库连接了。如果应用需要访问多个数据库,可以配置多个DB应用组件。dsn属性用来指明它的数据源名称,不用的数据库有不同的dsn格式,随用随查。

执行SQL语句

主要分三步:创建command,绑定参数(可选),调用SQL执行方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 返回多行. 每行都是列名和值的关联数组.
// 如果该查询没有结果则返回空数组
$posts = Yii::$app->db->createCommand('SELECT * FROM post')->queryAll();

// 返回一行 (第一行)
// 如果该查询没有结果则返回 false
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=1')->queryOne();

// 返回一列 (第一列)
// 如果该查询没有结果则返回空数组
$titles = Yii::$app->db->createCommand('SELECT title FROM post')->queryColumn();

// 返回一个标量值
// 如果该查询没有结果则返回 false
$count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM post')->queryScalar();

所有从数据库取得的数据都被表现为字符串。使用绑定参数的方法可以防止 SQL 注入攻击。在 SQL 语句中,可以嵌入一个或多个参数占位符。 一个参数占位符是以冒号开头的字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status')
->bindValue(':id', $_GET['id'])
->bindValue(':status', 1)
->queryOne();

#或使用:

$params = [':id' => $_GET['id'], ':status' => 1];

$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status')
->bindValues($params)
->queryOne();

$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status', $params)
->queryOne();

bindValue():绑定一个参数值
bindValues():在一次调用中绑定多个参数值

可以使用不同参数多次执行。

执行非查询语句,即不取回数据的语句,调用excute()方法,返回执行 SQL 所影响到的行数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Yii::$app->db->createCommand('UPDATE post SET status=1 WHERE id=1')
->execute();

// INSERT (table name, column values)
Yii::$app->db->createCommand()->insert('user', [
'name' => 'Sam',
'age' => 30,
])->execute();

// UPDATE (table name, column values, condition)
Yii::$app->db->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();

// DELETE (table name, condition)
Yii::$app->db->createCommand()->delete('user', 'status = 0')->execute();