1.情景展示
現在有這樣一種需求:
我需要建兩百多張表,這些表的表結構相同,表的名稱也是提前擬定好的,必須使用指定的表名;
如果使用一個個寫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
IF
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
FROM
@sqlstr;
EXECUTE stmt;
-- 游標往后移一位(相當於C里面的指針)
FETCH cur_table_name_list INTO var_table_name;
-- 結束循環
END WHILE;
-- 關閉游標
CLOSE cur_table_name_list;
END
把該語句粘貼到Navicat的新建SQL窗口當中,將其作為SQL執行即可完成存儲過程的創建;
切換到函數窗口,找到該存儲過程,雙擊打開;
點擊上圖當中的“運行” 按鈕,可以運行存儲過程。
涵蓋知識點:
存儲過程用法;
變量及局部變量用法;
游標用法;
循環用法;
預處理SQL用法。