mysql 存储过程中使用动态sql语句
Mysql 5.0 以后,支持了动态sql语句,我们可以通过传递不同的参数得到我们想要的值
这里介绍两种在存储过程中的动态sql:
set sql = (预处理的sql语句,可以是用concat拼接的语句)
set @sql = sql
PREPARE stmt_name FROM @sql;
EXECUTE stmt_name;
{DEALLOCATE | DROP} PREPARE stmt_name;

CREATE DEFINER = `root`@`%` PROCEDURE `NewProc`(IN `USER_ID` varchar(36),IN `USER_NAME` varchar(36))
BEGIN declare SQL_FOR_SELECT varchar(500); -- 定义预处理sql语句 set SQL_FOR_SELECT = CONCAT("select * from user where user_id = '",USER_ID,"' and user_name = '",USER_NAME,"'"); -- 拼接查询sql语句 set @sql = SQL_FOR_SELECT;
PREPARE stmt FROM @sql; -- 预处理动态sql语句
EXECUTE stmt ; -- 执行sql语句
deallocate prepare stmt; -- 释放prepare END;

上述是一个简单的查询用户表的存储过程,当我们调用此存储过程,可以根据传入不同的参数获得不同的值
但是:上述存储过程中,我们必须在拼接sql语句之前把USER_ID,USER_NAME定义好,而且在拼接sql语句之后,我们无法改变USER_ID,USER_NAME的值,如下

1 CREATE DEFINER = `root`@`%` PROCEDURE `NewProc`(IN `USER_ID` varchar(36),IN `USER_NAME` varchar(36))
2 BEGIN
3
4 declare SQL_FOR_SELECT varchar(500); -- 定义预处理sql语句
5
6 set SQL_FOR_SELECT = CONCAT("select * from user where user_id = '",USER_ID,"' and user_name = '",USER_NAME,"'"); -- 拼接查询sql语句
7
8 set @sql = SQL_FOR_SELECT;
9 PREPARE stmt FROM @sql; -- 预处理动态sql语句
10 EXECUTE stmt ; -- 执行sql语句
11 deallocate prepare stmt; -- 释放prepare
12
13
14 set USER_ID = '2';
15 set USER_NAME = 'lisi';
16
17 set @sql = SQL_FOR_SELECT;
18 PREPARE stmt FROM @sql; -- 预处理动态sql语句
19 EXECUTE stmt ; -- 执行sql语句
20 deallocate prepare stmt; -- 释放prepare
21 END;

我们用call aa('1','zhangsan');来调用该存储过程,第一次动态执行,我们得到了‘张三’的信息,然后我们在第14,15行将USER_ID,USER_NAME改为lisi,我们希望得到李四的相关信息,可查出来的结果依旧是张三的信息,说明我们在拼接sql语句后,不能再改变参数了。为了解决这种问题,下面介绍第二中方式
2.
set sql = (预处理的sql语句,可以是用concat拼接的语句,参数用 ?代替)
set @sql = sql
PREPARE stmt_name FROM @sql;
set @var_name = xxx;
EXECUTE stmt_name USING [USING @var_name [, @var_name] ...];
{DEALLOCATE | DROP} PREPARE stmt_name;
上述的代码我们就可以改成

1 CREATE DEFINER = `root`@`%` PROCEDURE `NewProc`(IN `USER_ID` varchar(36),IN `USER_NAME` varchar(36))
2 BEGIN
3
4 declare SQL_FOR_SELECT varchar(500); -- 定义预处理sql语句
5
6 set SQL_FOR_SELECT = "select * from user where user_id = ? and user_name = ? "; -- 拼接查询sql语句
7
8 set @sql = SQL_FOR_SELECT;
9 PREPARE stmt FROM @sql; -- 预处理动态sql语句
10
11 set @parm1 = USER_ID; -- 传递sql动态参数
12 set @parm2 = USER_NAME;
13
14 EXECUTE stmt USING @parm1 , @parm2; -- 执行sql语句
15 deallocate prepare stmt; -- 释放prepare
16
17
18 set @sql = SQL_FOR_SELECT;
19 PREPARE stmt FROM @sql; -- 预处理动态sql语句
20
21 set @parm1 = '2'; -- 传递sql动态参数
22 set @parm2 = 'lisi';
23
24 EXECUTE stmt USING @parm1 , @parm2; -- 执行sql语句
25 deallocate prepare stmt; -- 释放prepare
26 END;

这样,我们就可以真正的使用不同的参数(当然也可以在存储过程中通过逻辑生成不同的参数)来使用动态sql了。
几个注意:
- 存储动态SQL的值的变量不能是自定义变量,必须是用户变量或者全局变量 如:set sql = 'xxx'; prepare stmt from sql;是错的,正确为: set @sql = 'xxx'; prepare stmt from @sql;
即使 preparable_stmt 语句中的 ? 所代表的是一个字符串,你也不需要将 ? 用引号包含起来。
- 如果动态语句中用到了 in 则sql语句应该这样写:set @sql = "select * from user where user_id in (?,?,?) "
这里我也有个问题,因为有可能我不确定in语句里有几个参数,所以我试过这么写
set @sql = "select * from user where user_id in (?) "
然后参数我传的是 "'1','2','3'" 我以为程序会将我的动态sql解析出来(select * from user where user_id in ('1','2','3')) 但是并没有解析出来,各位大侠们帮帮忙,有什么好方法解决这个问题么?
转载至:https://www.cnblogs.com/fenxiangheiye/archive/2013/02/18/Mysql.html
mysql 存储过程中使用动态sql语句的更多相关文章
- 存储过程中执行动态Sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- 怎样SQL存储过程中执行动态SQL语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- 【转】MySQL存储过程中使用动态行转列
MySQL存储过程中使用动态行转列 最近做项目关于数据报表处理,然而数据库存储格式和报表展现形式不同,需要进行一下行转列的操作,在做上一个项目的时候也看了一下,但是后来换了读取方式,也就没深入研究这个 ...
- mybatis中的动态SQL语句
有时候,静态的SQL语句并不能满足应用程序的需求.我们可以根据一些条件,来动态地构建 SQL语句. 例如,在Web应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执 ...
- 如何找出MySQL数据库中的低效SQL语句
面对业务的迅猛发展,DBA的一项重要工作就是及时发现数据库中的低效SQL语句,有的可以立刻着手解决(比如缺少合适的索引),有的需要尽快反馈给开发人员进行修改. MySQL数据库有几个配置选项可以帮助我 ...
- MySQL存储过程中使用SELECT …INTO语句为变量赋值
使用SELECT …INTO语句为变量赋值 在MySQL存储过程中,可以使用SELECT …INTO语句对变量进行赋值,该语句在数据库中进行查询,并将得到的结果赋值给变量.SELECT …INTO语句 ...
- mysql 事务中如果有sql语句出错,会导致自动回滚吗?
事务,我们都知道具有原子性,操作要么全部成功,要么全部失败.但是有可能会造成误解. 我们先准备一张表,来进行测试 CREATE TABLE `name` ( `id` int(11) unsigned ...
- 阶段3 1.Mybatis_08.动态SQL_01.mybatis中的动态sql语句-if标签
创建新的工程 复制到新建的项目里面 pom.xml依赖部分复制过来 dao中整理代码 只保留四个查询 映射文件也只保留四个查询方法 增加一个根据条件查询的方法. 由于用了别名,所以parpameter ...
- SQL分页参数传值 在存储过程中使用 动态SQL实现
PROCEDURE [dbo].[SP_GetList] ( ), @arrearsStatus int, , --最小ID , --每页显示记录数 ) ) AS ); declare @strSQL ...
随机推荐
- 密码基础知识(2)以RSA为例说明加密、解密、签名、验签
密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...
- Mybatis和hibernate的优缺点比较
介绍: Hibernate :Hibernate 是当前最流行的ORM框架,对数据库结构提供了较为完整的封装. Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力点在于POJO 与S ...
- JavaWeb【一、简介】
原计划上周完成的内容,硬是过了一个清明拖到了这周,工作上还有很多东西没做...明天抓紧看把,争取这周末搞定 内容简介:(学习完后会重新梳理调整) 1.JavaWeb[一.简介] 2.JavaWeb[二 ...
- kali工具的总结
由于篇幅有限,只列举部分,ps:第一次发有什么不对的 还望各位大大指正 nc 瑞士军刀 [v1.10-41] 使用格式: nc [-参数] 主机名 端口[s] [端口] … 侦听入站: nc -l - ...
- Linux计划任务与压缩归档
计划任务分为两种形式 第一种:定时性的:也就是例行,每隔一定的周期就要重复来做这个任务. 第二种:突发性的:临时决定,只执行一次的任务. 用到的命令有两个 at:它是一个可以处理仅执行一次的任务就结束 ...
- Linux系统组成和获取命令帮助4
Linux文件系统: 1.文件名名称严格区分字符大小写 2.文件可以使用除/以外任意字符 3.文件名长度不能超过255字符 4.以.开头的文件为 ...
- Jmeter中间件处理-缓存
前言 消息队列和缓存是目前主流的中间件,我们在日常测试过程中,无论是接口还是压力测试,都会遇到需要处理这些中间件数据的情况.本文以Redis对缓存做一个简单的介绍,并基于Jmeter实现缓存数据处理. ...
- HH的项链 HYSBZ - 1878 (莫队/ 树状数组)
HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的项链变得越来越长.有一天,他突然 ...
- elk快速入门-filebeat
filebeatFilebeat是一个日志文件托运工具,在你的服务器上安装客户端后,filebeat会监控日志目录或者指定的日志文件,追踪读取这些文件(追踪文件的变化,不停的读),并且转发这些信息到e ...
- Summer training #11
A:水 #include <bits/stdc++.h> #include <cstring> #include <iostream> #include <a ...