mysql 存储过程 动态表名
今天写存储过程时,遇到要将表名最为参数的问题,如果不涉及到游标的话,使用prepare可以解决问题,但是,动态表名要运用在游标中的话,则prepare就得靠边站了。
集众人之智慧,最后,使用临时表解决了问题。
如何在MySQL的存储过程中实现把过程参数用在游标定义的SELECT命令里面作为表名引用
首先,我们来把场景描绘一下,比如下面的例子(当然是无法正确运行的):
CREATE PROCEDURE `proc`(SourceDBName CHAR(50), SourceTableName CHAR(50), TargetDBName CHAR(50), TargetTemplateTableName CHAR(50))
BEGINDECLARE 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;REPEATFETCH 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))
BEGINDECLARE 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))
BEGINDECLARE 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;REPEATFETCH 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))
BEGINCALL 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."
转自: WaveCN.com
mysql 存储过程 动态表名相关推荐
- MYSQL存储过程中 表名 使用变量
2019独角兽企业重金招聘Python工程师标准>>> # 该存储过程定义了几个传入参数,前缀都是para_ # 该存储过程的此部分功能是,查询根据传入参数动态生 ...
- mysql查询动态表名的数据类型_Mysql中查询某个数据库中所有表的字段信息
前言 有时候,需要在数据库中查询一些字段的具体信息,而这些字段又存在于不同的表中,那么我们如何来查询呢? 在每一个数据库链接的information_schema数据库中,存在这样一张表--COLUM ...
- mysql 动态创建事件_mysql 通过事件定时为数据库创建动态表名
#检测事件是否开启 show variables like 'event_scheduler'; #开启事件(最好在my.init设置,因为重启后还会变回默认值OFF) set global even ...
- mysql event scheduler机制 与 动态表名创建
mysql event scheduler机制 与 动态表名创建 今天有一个需求,需要定时在mysql创建表与删除表,以及根据日期命名表名.诚然,通过外部程序很容易实现与控制这一切. 但是需要额外的服 ...
- mysql下解决动态表名
之前在编写一段sql,内容如下:show create table ? 用占位符占了表名的坑,目的是查询建表语句,使用的模块是jdbcTemplate. 然而我发现,查询出来的结果是sql语法有 ...
- talend同步mysql_Talend可以为MySQL输出使用动态表名吗?
(用于数据集成的Talend OS) 可以使用动态表名吗?我已经研究了用户手册中的所有资源,尽管它们似乎都没有明确排除它,但我似乎无法使其正常工作. 情境 假设您有一个由1,000,000个名字组成的 ...
- mysql 存储过程建表_MySQL 存储过程创建表
创建 CREATE PROCEDURE Pro_IsExistTable(ableName varchar(100),out outputParam int) BEGIN set @csql=con ...
- Mybatis-Plus动态表名插件实现数据库分表查询
浮生若梦,就当它是梦,尽兴地梦它一场:世事如云,就当它是云,从容地观它千变万化. Mybatis-Plus中提供了各种插件,乐观锁.多租户.动态表名....今天来研究一下基于动态表名插件实现分表的案例 ...
- MyBatis-Plus动态表名插件使用
一.MyBatis-Plus动态表名插件使用 官方文档-动态表名插件:https://baomidou.com/pages/2a45ff/#dynamictablenameinnerintercept ...
最新文章
- 业界 | 每天1.4亿小时观看时长,Netflix怎样存储这些时间序列数据?
- 机器学习笔记:(时间序列中的线性回归)如何选择预测变量
- 4.4.6 数组也能无锁:AtomicIntegerArray
- 极详细的ECC讲解 -OOB与ECC
- 第一代计算机主要应用领域为数据处理,第一代计算机主要应用领域为____。 A.数据处理 B.人工智能 C.科学计算 D.过程控制...
- S5PV210裸机之GPIO
- 七种程序员的基本技能
- android studio 创建项目失败原因Failed to create
- 2013 Esri全球用户大会QA之元数据支持
- Java 基本数据类型存储位置
- 手机如何安装java软件_如何在手机上安装JAVA平台
- PowerDesigner 反向工程获取数据库表结构
- linux下,代码阅读工具,understand
- 将uiimageview设置成纯圆形
- 高德地图自定义点标记大小_高德地图 自定义点标记 图标大小
- win10浏览器闪退_Win10 Build 14942 Edge 浏览器闪退怎么解决?
- 云平台 物联网 概念 数据挖掘技术
- [RK3288][Android6.0] 调试笔记 --- ro.serialno的获取
- 【C++】对象的定义、初始化与赋值
- Python Pdb源码解析