预处理语句
从 v3.2 版本开始,StarRocks 提供预处理语句,用于多次执行具有相同结构但不同变量的 SQL 语句。 此功能显着提高了执行效率并防止了 SQL 注入。
描述
预处理语句的基本工作方式如下
- 准备:用户准备一个 SQL 语句,其中变量由占位符
?
表示。 FE 解析 SQL 语句并生成执行计划。 - 执行:声明变量后,用户将这些变量传递给语句并执行该语句。 用户可以使用不同的变量多次执行同一语句。
优点
- 节省了解析的开销:在实际业务场景中,应用程序通常使用相同的结构但不同的变量多次执行语句。 通过预处理语句的支持,StarRocks 只需要在准备阶段解析一次语句。 使用不同变量的同一语句的后续执行可以直接使用预先生成的解析结果。 因此,语句执行性能显着提高,尤其是对于复杂的查询。
- 防止 SQL 注入攻击:通过将语句与变量分离,并将用户输入的数据作为参数传递,而不是直接将变量连接到语句中,StarRocks 可以防止恶意用户执行恶意 SQL 代码。
用法
预处理语句仅在当前会话中有效,不能在其他会话中使用。 当前会话退出后,在该会话中创建的预处理语句将自动删除。
语法
预处理语句的执行包括以下阶段
- PREPARE:准备语句,其中变量由占位符
?
表示。 - SET:声明语句中的变量。
- EXECUTE:将声明的变量传递给语句并执行它。
- DROP PREPARE 或 DEALLOCATE PREPARE:删除预处理语句。
PREPARE
语法
PREPARE <stmt_name> FROM <preparable_stmt>
参数
stmt_name
:赋予预处理语句的名称,该名称随后用于执行或释放该预处理语句。 该名称在单个会话中必须是唯一的。preparable_stmt
:要准备的 SQL 语句,其中变量的占位符是一个问号 (?
)。 目前,仅支持SELECT
语句。
示例
准备一个 SELECT
语句,其中特定值由占位符 ?
表示。
PREPARE select_by_id_stmt FROM 'SELECT * FROM users WHERE id = ?';
SET
语法
SET @var_name = expr [, ...];
参数
var_name
:用户定义的变量的名称。expr
:用户定义的变量。
示例: 声明变量。
SET @id1 = 1, @id2 = 2;
有关更多信息,请参见 用户定义变量。
EXECUTE
语法
EXECUTE <stmt_name> [USING @var_name [, @var_name] ...]
参数
var_name
:在SET
语句中声明的变量的名称。stmt_name
:预处理语句的名称。
示例
将变量传递给 SELECT
语句并执行该语句。
EXECUTE select_by_id_stmt USING @id1;
DROP PREPARE 或 DEALLOCATE PREPARE
语法
{DEALLOCATE | DROP} PREPARE <stmt_name>
参数
stmt_name
:预处理语句的名称。
示例
删除预处理语句。
DROP PREPARE select_by_id_stmt;
示例
使用预处理语句
以下示例演示了如何使用预处理语句从 StarRocks 表中插入、删除、更新和查询数据
假设以下名为 demo
的数据库和名为 users
的表已经创建
CREATE DATABASE IF NOT EXISTS demo;
USE demo;
CREATE TABLE users (
id BIGINT NOT NULL,
country STRING,
city STRING,
revenue BIGINT
)
PRIMARY KEY (id)
DISTRIBUTED BY HASH(id);
-
准备要执行的语句。
PREPARE select_all_stmt FROM 'SELECT * FROM users';
PREPARE select_by_id_stmt FROM 'SELECT * FROM users WHERE id = ?'; -
在这些语句中声明变量。
SET @id1 = 1, @id2 = 2;
-
使用声明的变量来执行语句。
-- Query all data from the table.
EXECUTE select_all_stmt;
-- Query data with ID 1 or 2 separately.
EXECUTE select_by_id_stmt USING @id1;
EXECUTE select_by_id_stmt USING @id2;
在 Java 应用程序中使用预处理语句
以下示例演示了 Java 应用程序如何使用 JDBC 驱动程序从 StarRocks 表中插入、删除、更新和查询数据
-
在 JDBC 中指定 StarRocks 的连接 URL 时,需要启用服务器端预处理语句
jdbc:mysql://<fe_ip>:<fe_query_port>/useServerPrepStmts=true
-
StarRocks GitHub 项目提供了一个 Java 代码示例,该示例解释了如何通过 JDBC 驱动程序从 StarRocks 表中插入、删除、更新和查询数据。