📅  最后修改于: 2020-11-19 02:18:43             🧑  作者: Mango
在MySQL 4.1版之前,每个查询都以文本格式发送到MySQL服务器,并使用文本协议将查询返回的数据返回给客户端。在将结果返回给客户端之前,MySQL已完全解析了查询并将结果集转换为字符串。在这里,解析意味着对提交的查询进行语法和语义上的验证,并且特权也得到验证。
将数据返回给客户端的文本协议存在严重的性能问题。为了克服这个问题,MySQL从4.1版本开始提供了一种称为“预处理语句”的新功能。
准备的语句或参数化的语句用于高效重复执行相同的语句。它利用了客户端/服务器二进制协议。 Prepared语句将包含占位符(?)的查询传递给MySQL Server。请参见以下示例:
mysql> SELECT * FROM student WHERE studentId = ?;
当MySQL使用不同的studentId值执行上述语句时,它无法完全分析该语句。结果,MySQL将更快地执行该语句,尤其是当它多次执行相同的查询时。
准备好的语句包含占位符(?),它有助于避免许多SQL注入变体,并使我们的应用程序更安全。
以下是MySQL中预处理语句的优点:
准备好的语句的基本工作流程主要包括两个阶段。但是,它具有一个可选阶段,总结如下:
在准备阶段,一个语句模板被发送到数据库服务器。服务器执行语法检查并初始化内部服务器资源以供以后使用。简而言之,它准备执行语句。
句法
以下是准备阶段的语法:
PREPARE stmt_name FROM preparable_stmt;
在执行阶段,客户端绑定参数值,并将其发送到服务器。服务器根据语句模板和绑定值创建一条语句,以使用先前创建的内部资源执行该语句。简而言之,一旦准备好的语句准备好查询,我们就准备执行该查询。
句法
以下是执行准备好的语句的语法:
EXECUTE stmt_name [USING @var_name [, @var_name]....]
这是最后一个可选阶段,用于释放准备好的语句。
句法
以下是取消分配准备好的语句的语法:
{DEALLOCATE | DROP} PREPARE stmt_name;
让我们通过一些例子来了解如何使用MySQL预处理语句。
在这里,我们将借助PREPARE语句直接创建一个语句,如下所示:
mysql> PREPARE stmt1 FROM 'SELECT ?+? AS SUM';
接下来,我们将两个值分配给两个可用于占位符(?)的变量:
mysql> SET @a = 20;
mysql> SET @b = 30;
现在,我们可以借助EXECUTE语句执行查询:
mysql> EXECUTE stmt1 USING @a, @b;
执行后,我们将得到结果的总和。请参见下图以了解结果:
以下示例将使用示例数据库中的employee表,该表包含以下数据。
首先,我们将准备一条语句,该语句返回由员工ID指定的员工姓名和职务:
mysql> PREPARE stmt1 FROM
'SELECT Name, Designation FROM employee
WHERE Emp_id = ?';
接下来,我们需要声明一个名为id的变量并将其值设置为“ 1”:
mysql> SET @id = 1;
现在,我们可以在EXECUTE语句的帮助下执行准备好的语句:
mysql> EXECUTE stmt1 USING @id;
执行后,我们将得到包含雇员姓名和职务的结果。请参见下图以了解查询执行:
同样,我们将为变量id分配另一个值:
mysql> SET @id = 3;
现在,使用新的员工ID执行准备好的语句。我们将看到如下输出:
最后,我们可以手动释放准备好的语句。但是,它们将在会话关闭时自动删除。
mysql> DEALLOCATE PREPARE stmt1;
如果在执行上述查询后尝试执行预处理语句,则会收到如下错误:
通过将准备好的语句写入到BEGIN和END块中,可以在存储过程中使用它。我们可以通过创建一个示例来理解它,该示例通过将表名作为存储过程的参数传递来返回表中的所有记录。
创建存储过程,如下所示:
DELIMITER $$
CREATE PROCEDURE tbl_detail(tab_name Varchar(40))
BEGIN
SET @A:= CONCAT('Select * from',' ',tab_name);
Prepare stmt FROM @A;
EXECUTE stmt;
END$$
DELIMITER ;
请参见下图执行存储过程:
创建成功后,我们可以通过将表名称指定为其参数来调用此过程。
mysql> CALL tbl_detail('employee');
它将显示表的所有记录。见下图:
以下是MySQL中的语句和预准备语句之间的主要区别:
Statement | Prepared Statement |
---|---|
It is used when we want to execute the SQL query only once. | It is used when we want to execute the SQL query multiple times. |
It is used for DDL statements. | It can be used for any SQL query. |
It cannot be used to read and write binary data. | It can be used to read and write binary data. |
It is static, which means we cannot pass parameters at runtime. | It is dynamic, which means we can pass parameters at runtime. |
The performance of execution is slow. | The performance of execution is fast. |
It does not prevent SQL injection. | It helps to prevent SQL injection attacks. |
It uses a textual protocol for communication. | It uses a binary protocol for communication. |
以下是存储过程和MySQL中的prepared语句之间的主要区别:
Stored Procedure | Prepared Statement |
---|---|
Stored procedures are a sequence of SQL statements that access the relational database management system. | Prepared statements are queries that contain the placeholders instead of actual values. |
It can be stored in the database server. | It cannot be stored in the database. |