现在有这样一种需求:

我需要建两百多张表,这些表的表结构相同,表的名称也是提前拟定好的,必须使用指定的表名;

如果使用一个个写SQL语句,那不还得累死,所以,我想到了可不可以通过批量建表来实现?

2.原因分析

既然是只有表名不同,那我们只需要写好建表语句,中间的表名使用动态赋值的方式,for循环执行就可以了。

这就涉及到如何取值的问题?

你可以按照mysql的语句for循环取表名,也可以将表名放到游标里,循环游标取值;

由于我这里使用游标最方便,所以本文将使用游标来实现。

3.解决方案

需要使用:存储过程、游标、循环、SQL语句预处理。

建表语句分析:

我们先来回顾一下建表语句:create table 表名 (表字段...);

我们需要将表名使用变量来替代,也就是:create table variable_name (field...);

但是,建表语句,不识别变量,它只会将variable_name当成字符串,而不是变量来处理,也就是说,我们永远只能建一张表名为:variable_name的表。

那就只能使用最笨的方法:字符串拼接,即可,先将建表语句以字符串拼接的方式组装好,然后在执行。

CREATE PROCEDURE create_table_batch()
BEGIN
  -- 该变量用于标识是否还有数据需遍历
	DECLARE
		var_flag INT DEFAULT 0;
	-- 创建一个变量用来存储遍历过程中的值
	DECLARE
		var_table_name VARCHAR ( 255 );
	-- 查询出需要遍历的数据集合
	DECLARE
		cur_table_name_list CURSOR FOR ( SELECT TABLENAME FROM meta_theme WHERE THEMETYPE = 2 );
	-- 查询是否有下一个数据,没有将标识设为1,相当于hasNext
	DECLARE
		CONTINUE HANDLER FOR NOT FOUND 
		SET var_flag = 1;
	-- 打开游标
	OPEN cur_table_name_list;
	-- 将游标中的值赋给定义好的变量(for循环的关键)
	-- 注意:当变量名与表的字段名相同时,游标fetch注入的变量为null,即使大小写不一致
	FETCH cur_table_name_list INTO var_table_name;
	-- 遍历未结束就一直执行
	WHILE
			var_flag != 1 DO
		-- targetSQL:for循环需要执行的核心代码
		/*DROP TABLE
			EXISTS var_table_name;
		CREATE TABLE var_table_name (
			ID BIGINT ( 20 ) NOT NULL AUTO_INCREMENT COMMENT '主键',
			DATAIDENTIFIER VARCHAR ( 255 ) COMMENT '数据元标识符',
			ENGLISHCODE VARCHAR ( 255 ) COMMENT '英文编码',
			CHINESENAME VARCHAR ( 255 ) COMMENT '中文名称',
			DEFINITION VARCHAR ( 255 ) COMMENT '定义',
			FIELDTYPE VARCHAR ( 255 ) COMMENT '字段类型',
			FIELDDESCRIPTION VARCHAR ( 255 ) COMMENT '字段说明',
			RANGCODE VARCHAR ( 255 ) COMMENT '值域代码',
			PRIMARY KEY ( ID ) USING BTREE 
		) ENGINE = INNODB CHARACTER 
		SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;*/
        -- 局部变量必须以@作为前缀,声明方式用set
        -- 拼接建表SQL字符串,表名为变量
        SET @sqlstr = CONCAT( "CREATE TABLE ", var_table_name, " (
				ID bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
				DATAIDENTIFIER varchar(255) COMMENT '数据元标识符',
				ENGLISHCODE varchar(255) COMMENT '英文编码',
				CHINESENAME varchar(255) COMMENT '中文名称',
				DEFINITION varchar(255) COMMENT '定义',
				FIELDTYPE varchar(255) COMMENT '字段类型',
				FIELDDESCRIPTION varchar(255) COMMENT '字段说明',
				RANGCODE varchar(255) COMMENT '值域代码',
				PRIMARY KEY (ID) USING BTREE
				) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic
		-- mysql 预处理	SQL语句固定用法
		PREPARE stmt 
			@sqlstr;
		EXECUTE stmt;
		-- 游标往后移一位(相当于C里面的指针)
		FETCH cur_table_name_list INTO var_table_name;
	-- 结束循环	
	END WHILE;
	-- 关闭游标
	CLOSE cur_table_name_list;

把该语句粘贴到Navicat的新建SQL窗口当中,将其作为SQL执行即可完成存储过程的创建;

切换到函数窗口,找到该存储过程,双击打开;

点击上图当中的“运行” 按钮,可以运行存储过程。

涵盖知识点:

存储过程用法;

变量及局部变量用法;

游标用法;

循环用法;

预处理SQL用法。

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐:

  • mysql 存储过程 示例
  •