mysql 存储过程 动态表名
今天写存储过程时,遇到要将表名最为参数的问题,如果不涉及到游标的话,使用prepare可以解决问题,但是,动态表名要运用在游标中的话,则prepare就得靠边站了。
集众人之智慧,最后,使用临时表解决了问题。
如何在MySQL的存储过程中实现把过程参数用在游标定义的SELECT命令里面作为表名引用
首先,我们来把场景描绘一下,比如下面的例子(当然是无法正确运行的):
- CREATE PROCEDURE `proc`(SourceDBName CHAR(50), SourceTableName CHAR(50),
- TargetDBName CHAR(50), TargetTemplateTableName CHAR(50))
- BEGIN
- DECLARE done INT DEFAULT 0;
- DECLARE FieldValue CHAR(50);
- DECLARE CursorSegment CURSOR FOR SELECT ... FROM SourceDBName.SourceTableName;
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
- OPEN CursorSegment;
- REPEAT
- FETCH CursorSegment INTO FieldValue;
- IF NOT done THEN
- ...
- END IF;
- UNTIL done END REPEAT;
- CLOSE CursorSegment;
- END$$
上面的例子试图通过存储过程的参数传递,向存储过程内部的游标定义传递要SELECT的数据库名称和表名称。但是,这个存储过程在运行时MySQL会提示“SourceDBName.SourceTableName”不存在。也就是说MySQL不会把SourceDBName和SourceTableName两个标识符作为局部变量去解析,而是直接作为表引用。
要解决这个问题,唯一的方法就是把上面这个存储过程分为3个存储过程。对,3个。所以说这是一个比较复杂的解决办法。
第一个存储过程,扮演的是数据收集器的角色。它接收参数传递过来的数据库名和表名,然后把数据SELECT到一个临时表中。需要注意,临时表的最大好处是它是线程安全的。
第二个存储过程,基于第一个存储过程生成的临时表而创建游标,并处理具体的工作。
第三个存储过程,作为一个入口,负责依次调用存储过程1和存储过程2,并提供相应的参数。
三个存储过程综合起来,就得到下面的例子:
- CREATE PROCEDURE `proc1`(SourceDBName CHAR(50), SourceTableName CHAR(50))
- BEGIN
- DECLARE SQLStmt TEXT;
- SET SQL_NOTES=0;
- SET @SQLStmt = CONCAT('DROP TEMPORARY TABLE IF EXISTS tmp_table_name');
- PREPARE Stmt FROM @SQLStmt;
- EXECUTE Stmt;
- DEALLOCATE PREPARE Stmt;
- SET @SQLStmt = CONCAT('CREATE TEMPORARY TABLE tmp_table_name SELECT ... FROM ',
- SourceDBName,'.',SourceTableName,' WHERE ... ');
- PREPARE Stmt FROM @SQLStmt;
- EXECUTE Stmt;
- DEALLOCATE PREPARE Stmt;
- END$$
- CREATE PROCEDURE `proc2`(TargetDBName CHAR(50), TargetTemplateTableName CHAR(50))
- BEGIN
- DECLARE done INT DEFAULT 0;
- DECLARE FieldValue CHAR(50);
- DECLARE CursorSegment CURSOR FOR SELECT Period FROM tmp_table_name;
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
- OPEN CursorSegment;
- REPEAT
- FETCH CursorSegment INTO FieldValue;
- IF NOT done THEN
- ...
- END IF;
- UNTIL done END REPEAT;
- CLOSE CursorSegment;
- END$$
- CREATE PROCEDURE `proc3`(SourceDBName CHAR(50), SourceTableName CHAR(50),
- TargetDBName CHAR(50), TargetTemplateTableName CHAR(50))
- BEGIN
- CALL proc1(SourceDBName, SourceTableName);
- CALL proc2(TargetDBName, TargetTemplateTableName);
- END$$
补充:运行前需要把系统参数变量“sql_notes”设置为0,否则proc1在DROP TABLE时会停下来。原因是
- "SQL_NOTES = {0 | 1}
- If set to 1 (the default), warnings of Note level are recorded.
- If set to 0, Note warnings are suppressed."
mysql 存储过程 动态表名的更多相关文章
- mysql的动态表名
create EVENT createMtpulseTable ON SCHEDULE every 1 month STARTS CURRENT_TIMESTAMP DO CALL pro_creat ...
- 关于mysql存储过程创建动态表名及參数处理
转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog) 近期游戏開始第二次内測,開始处理操作日志.最開始把日志放到同一个表里面,发现一天时间,平均100玩家 ...
- MySQL中将数据库表名修改成大写的存储过程
原文:MySQL中将数据库表名修改成大写的存储过程 MySQL中将数据库表名修改成大写的存储过程 创建存储过程的代码: DROP PROCEDURE IF EXISTS uppercaseTablen ...
- Oracle中存储过程传入表名学习
Oracle中存储过程传入表名: 一.动态清除该表的数据 create or replace procedure p_deletetable(i_tableName in varchar2) as ...
- hibernate动态表名映射
引自:http://blog.csdn.net/xvshu/article/details/39187779 最近的一个项目有一个需求,有N个考核单位,要对每个考核单位生成一张考核情况表,这样做的目的 ...
- 设置Linux中的Mysql不区分表名大小写
1. MySQL数据库的表名在Linux系统下是严格区分大小写的,在Windows系统下开发的程序移植到Linux系统下,如果程序中SQL语句没有严格按照大小写访问数据库表,就可能会出现找不到表的错误 ...
- MySQL获取Schema表名和字段信息
MySQL获取Schema表名和字段信息 获取表名 select TABLE_NAME,TABLE_TYPE,ENGINE,TABLE_ROWS,TABLE_COMMENT,CREATE_TIME,U ...
- 使用dao时,如何同时使用动态表名和过滤字段?
使用dao时,如何同时使用动态表名和过滤字段? 发布于 630天前 作者 wukonggg 316 次浏览 复制 上一个帖子 下一个帖子 标签: 无 如题.求样例代码 1 回复 wend ...
- MYSQL 存储过程 多表更新异常捕捉和异常处理方式
今天在做MYSQL 存储过程 多表更新的功能 多表更新时候注意事项 1.首先是确保多表更新能够一次执行,途中没有哪个表的sql语句错误 2.上线后修改表结构及字段,请注意检查是否影响mysql 过 ...
随机推荐
- 2019 网宿科技java面试笔试题 (含面试题解析)
本人3年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.网宿科技等公司offer,岗位是Java后端开发,最终选择去了网宿科技. 面试了很多家公司,感觉大部分公司考察的点 ...
- 易百教程人工智能python修正-人工智能NLTK性别发现器
在这个问题陈述中,将通过提供名字来训练分类器以找到性别(男性或女性). 我们需要使用启发式构造特征向量并训练分类器.这里使用scikit-learn软件包中的标签数据. 以下是构建性别查找器的Pyth ...
- python关于try except的使用方法
一.常见错误总结 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常;基本上是无法打开文件 ImportError 无法引入 ...
- DameWare入侵
下载Dameware 去官网下载Dameware,并安装 添加被控端ip 选择Mini连接方式 安装服务到被控端 安装前配置,点击"Install"按钮 如图所示,将选项勾选,并点 ...
- SAP错误消息调试之七种武器:让所有的错误消息都能被定位
目录 长生剑 - SAPGUI Where Used List 碧玉刀 - ABAP调试器观察点 霸王枪 - ABAP调试器动态断点 多情环 - ABAP代码静态扫描 孔雀翎 - SAT 离别钩 - ...
- IVS_技术
视频监控技术按照设备发展过程分为三个阶段:模拟视频监控.数字视频监控.智能视频监控,如下图: 模拟视频监控 第一代视频监控系统也叫做闭路电视监控系统,简称CCTV(Close Circuit Tele ...
- 分布式数据库中间件、产品——sharding-jdbc、mycat、drds
一般对于业务记录类随时间会不断增加的数据,当数据量增加到一定量(一般认为整型值为主的表达到千万级,字符串为主的表达到五百万)的时候,性能将遇到瓶颈,同时调整表结构也会变得非常困难.为了避免生产遇到这样 ...
- windows 任务计划
我的需求是每天定时访问网站的某一个控制器去刷新库存 流程如下(我自己的理解) 进入任务计划页面 上图指定的bat文件内容就是访问指定的网站路径 dingshi.bat文件内容如下(这个是网上找的,可能 ...
- vue 使用moment
1.下载 cnpm i moment --save 2.main.js 挂载 import moment from 'moment'//导入文件 Vue.prototype.$moment = mo ...
- 解决pycharm导入pygame包问题
在正确用pip命令安装好pygame后, 运行pycharm仍然会报错找不到pygame包, 这时候我们可以用pycharm自带的工具安装好pygame包,操作步骤如下: 点击设置,(或者ctrl+a ...