今天写存储过程时,遇到要将表名最为参数的问题,如果不涉及到游标的话,使用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 存储过程 动态表名相关推荐

  1. MYSQL存储过程中 表名 使用变量

    2019独角兽企业重金招聘Python工程师标准>>> #      该存储过程定义了几个传入参数,前缀都是para_ #      该存储过程的此部分功能是,查询根据传入参数动态生 ...

  2. mysql查询动态表名的数据类型_Mysql中查询某个数据库中所有表的字段信息

    前言 有时候,需要在数据库中查询一些字段的具体信息,而这些字段又存在于不同的表中,那么我们如何来查询呢? 在每一个数据库链接的information_schema数据库中,存在这样一张表--COLUM ...

  3. mysql 动态创建事件_mysql 通过事件定时为数据库创建动态表名

    #检测事件是否开启 show variables like 'event_scheduler'; #开启事件(最好在my.init设置,因为重启后还会变回默认值OFF) set global even ...

  4. mysql event scheduler机制 与 动态表名创建

    mysql event scheduler机制 与 动态表名创建 今天有一个需求,需要定时在mysql创建表与删除表,以及根据日期命名表名.诚然,通过外部程序很容易实现与控制这一切. 但是需要额外的服 ...

  5. mysql下解决动态表名

    之前在编写一段sql,内容如下:show create table ?    用占位符占了表名的坑,目的是查询建表语句,使用的模块是jdbcTemplate. 然而我发现,查询出来的结果是sql语法有 ...

  6. talend同步mysql_Talend可以为MySQL输出使用动态表名吗?

    (用于数据集成的Talend OS) 可以使用动态表名吗?我已经研究了用户手册中的所有资源,尽管它们似乎都没有明确排除它,但我似乎无法使其正常工作. 情境 假设您有一个由1,000,000个名字组成的 ...

  7. mysql 存储过程建表_MySQL 存储过程创建表

    创建 CREATE PROCEDURE  Pro_IsExistTable(ableName varchar(100),out outputParam int) BEGIN set @csql=con ...

  8. Mybatis-Plus动态表名插件实现数据库分表查询

    浮生若梦,就当它是梦,尽兴地梦它一场:世事如云,就当它是云,从容地观它千变万化. Mybatis-Plus中提供了各种插件,乐观锁.多租户.动态表名....今天来研究一下基于动态表名插件实现分表的案例 ...

  9. MyBatis-Plus动态表名插件使用

    一.MyBatis-Plus动态表名插件使用 官方文档-动态表名插件:https://baomidou.com/pages/2a45ff/#dynamictablenameinnerintercept ...

最新文章

  1. 业界 | 每天1.4亿小时观看时长,Netflix怎样存储这些时间序列数据?
  2. 机器学习笔记:(时间序列中的线性回归)如何选择预测变量
  3. 4.4.6 数组也能无锁:AtomicIntegerArray
  4. 极详细的ECC讲解 -OOB与ECC
  5. 第一代计算机主要应用领域为数据处理,第一代计算机主要应用领域为____。    A.数据处理 B.人工智能 C.科学计算 D.过程控制...
  6. S5PV210裸机之GPIO
  7. 七种程序员的基本技能
  8. android studio 创建项目失败原因Failed to create
  9. 2013 Esri全球用户大会QA之元数据支持
  10. Java 基本数据类型存储位置
  11. 手机如何安装java软件_如何在手机上安装JAVA平台
  12. PowerDesigner 反向工程获取数据库表结构
  13. linux下,代码阅读工具,understand
  14. 将uiimageview设置成纯圆形
  15. 高德地图自定义点标记大小_高德地图 自定义点标记 图标大小
  16. win10浏览器闪退_Win10 Build 14942 Edge 浏览器闪退怎么解决?
  17. 云平台 物联网 概念 数据挖掘技术
  18. [RK3288][Android6.0] 调试笔记 --- ro.serialno的获取
  19. 【C++】对象的定义、初始化与赋值
  20. Python Pdb源码解析

热门文章

  1. 回顾2016年存储市场发展 解析产品涨价为何如此逆天
  2. google海底光缆图_SubmarineCableMap:世界海底光缆分布图
  3. Flash组件按钮的使用详解
  4. SLA文档+中学部教练有悟
  5. 唯品会php接口,唯品会VIP-开放平台
  6. UICollectionView 自定义布局教程: Pinterest
  7. 刷微博粉丝工具发布及原理解说
  8. 艾永亮:戴森,你凭什么卖得这么贵?
  9. 【计算机组成原理】门阵列译码器
  10. linux 红帽 服务dns,Linux小红帽搭建dns服务器