mysql 不创建存储过程的方式动态组装sql

有些时候我们会动态组装一些sql,但是又不想创建一个存储过程,mysql正好有个方式支持的。

那就是Prepared SQL Statement Syntax

官方文档链接如下

https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-prepared-statements.html

另外也参考了如下文章,感谢提供的思路。

https://www.cnblogs.com/leodaxin/p/10340651.html

 

简单来说有两种方式

The first example shows how to create a prepared statement by using a string literal to supply the text of the statement:

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;

The second example is similar, but supplies the text of the statement as a user variable:

mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 
mysql> PREPARE stmt2 FROM @s; 
mysql> SET @a = 6; 
mysql> SET @b = 8; 
mysql> EXECUTE stmt2 USING @a, @b;
 +------------+ 
| hypotenuse | 
+------------+ 
| 10 | 
+------------+ 
mysql> DEALLOCATE PREPARE stmt2;

 

我这边使用的第二种方式,因为表名是动态的,没有参数,需要根据当前时间取分表名称。

set @s = concat('select * from table-',date_formate(now(),'%Y'%m'));

prepare st from @s;

execute st;

deallocate prepare st;

允许使用的关键字

SQL Syntax Allowed in Prepared Statements

The following SQL statements can be used as prepared statements:

ALTER TABLE ALTER USER ANALYZE TABLE CACHE INDEX CALL CHANGE MASTER CHECKSUM {TABLE | TABLES} COMMIT {CREATE | DROP} INDEX {CREATE | RENAME | DROP} DATABASE {CREATE | DROP} TABLE {CREATE | RENAME | DROP} USER {CREATE | DROP} VIEW DELETE DO FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | USER_RESOURCES} GRANT INSERT INSTALL PLUGIN KILL LOAD INDEX INTO CACHE OPTIMIZE TABLE RENAME TABLE REPAIR TABLE REPLACE RESET {MASTER | SLAVE} REVOKE SELECT SET SHOW {WARNINGS | ERRORS} SHOW BINLOG EVENTS SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW} SHOW {MASTER | BINARY} LOGS SHOW {MASTER | SLAVE} STATUS SLAVE {START | STOP} TRUNCATE TABLE UNINSTALL PLUGIN UPDATE

### 动态行转列的 SQL 查询 在 MySQL 中实现动态行转列可以通过使用预处理语句来完成。由于 MySQL 支持直接传递列名作为参数,因此需要构建一个包含所需列名的字符串,并将其转换为可执行的 SQL 语句。 #### 使用 PREPARE 和 EXECUTE 实现动态行转列 为了创建动态行转列的功能,可以按照以下方式操作: 1. **收集所有可能的列名** 首先获取所有需要转换成列的数据项。这通常是从某个字段中提取唯一值。假设有一个名为 `sales` 的表,其中有一列表示产品类别 (`category`) 及其对应的销售数量 (`quantity`)。 ```sql SELECT DISTINCT category FROM sales; ``` 2. **构造 GROUP_CONCAT 函数用于生成 CASE 表达式** 接下来利用这些唯一的分类名称构建一系列 `CASE WHEN ... THEN ... END AS 'column_name'` 形式的表达式。这里会用到 `GROUP_CONCAT()` 来连接多个这样的表达式形成完整的 SELECT 子句部分。 ```sql SET @columns = ( SELECT GROUP_CONCAT( CONCAT('MAX(CASE WHEN category = ''', category, ''' THEN quantity ELSE NULL END) AS ', QUOTE(category)) ) FROM (SELECT DISTINCT category FROM sales) t ); ``` 3. **组合最终查询并准备执行** 最后一步就是把之前得到的结果组装起来构成整个查询语句,并通过 `PREPARE` 和 `EXECUTE` 命令去运行它。 ```sql SET @sql = CONCAT('SELECT date, ', @columns, ' FROM sales GROUP BY date'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; ``` 上述过程展示了如何基于特定需求自动生成所需的列并将它们应用到查询当中[^2]。 4. **确保安全性** 当涉及到用户输入或其他外部源提供的数据时,务必采取措施防止 SQL 注入攻击。一种做法是在拼接前对任何来自用户的输入进行严格的验证和清理;另一种则是尽可能多地依赖于参数化查询或存储过程[^3]。 5. **遵循良好的编码习惯** 保持清晰易读的代码结构有助于后期维护工作。对于复杂的查询建议分步调试,逐步确认每一段子查询是否按预期返回结果。此外,在适当的地方添加注释说明意图也能极大地方便他人理解这段程序的工作原理[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值