マスターDBがあります。マスターDBの複製DBを作成したいのですが、すべてのテーブルを指定しただけではありません。
カンマ区切りの文字列でこれらのテーブル名を持っています。 tbl1, tbl2, tbl7, tbl10
など.
私はそれを渡すストアドプロシージャを作成しようとしていますnew DB name
これにより、DBが作成され、指定されたテーブルがそれに複製されます。これまでのところ2つありますが、ループする方法がわかりません。私はDBが初めてなので、これを達成する方法を教えてください。
(注)配列を使用してループできるかどうかはわかりませんが、テーブル名は配列変数に格納できます。テーブル名はハードコーディング
以下は私が望むSudoコードです。
CREATE DATABASE %param_db%;
@tables = 'tbl1, tbl2, tbl7, tbl10';
loop through @tables as table_name
CREATE TABLE %param_db.table_name% LIKE Master.%table_name%;
End loop
ストアドプロシージャでレイアウトする手順は次のとおりです
これがそのストアドプロシージャです
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`TableCookieCutter` $$
CREATE PROCEDURE `test`.`TableCookieCutter`
(
SourceDB VARCHAR(64),
TargetDB VARCHAR(64),
TableList VARCHAR(1024)
)
BEGIN
# Create the Target DB
SET @sql = CONCAT('CREATE DATABASE IF NOT EXISTS ',TargetDB);
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
# Strip Table List of Blanks
# Enclose each table in quotes
SET @table_list = CONCAT('''',REPLACE(REPLACE(TableList ,' ',''),',',QUOTE(',')),'''');
# Count the number of tables in the list
SET @table_stub = REPLACE(@table_list,',','');
SET @array_count = LENGTH(@table_list) - LENGTH(@table_stub) + 1;
# Loop through list of tables, creating each table
SET @x = 0;
WHILE @x < @array_count DO
SET @x = @x + 1;
SET @sql = CONCAT('SELECT ELT(',@x,',',@table_list,') INTO @tb');
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
SET @sql = CONCAT('CREATE TABLE ',TargetDB,'.',@tb,' LIKE ',SourceDB,'.',@tb);
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
END WHILE;
END $$
DELIMITER ;
@RolandoMySQLDBAが最初に投稿しますが、別の方法があります。
これを 分割されたコンマ文字列区切り および これは発生数 に使用して、このストアドプロシージャを作成しました。
CREATE DEFINER=`root`@`localhost` PROCEDURE `spCreateRplDB`(
IN iNewDB VARCHAR(100),
IN iOldDB VARCHAR(100),
IN iTables VARCHAR(150))
BEGIN
# Comma separated string
SET @repldb=iNewDB;
SET @masterdb=iOldDB;
SET @tbls=TRIM(iTables);
SET @counter=(SELECT ROUND((LENGTH(@tbls) - LENGTH( REPLACE (@tbls, ",", ""))) / LENGTH(",")));
SET @loop_num=0;
# Splitting comma separated string
IF (@counter>0 && @repldb<>'' && @masterdb <> '') THEN
SET @counter=@counter+1; # [ ADDING +1 BECAUSE @counter JUST COUNT THE NUMBER OF OCCURENCES OF A STRING INSIDE @tbls ]
# Creating DB if not exists
SET @database_create=CONCAT(" CREATE DATABASE IF NOT EXISTS ",@repldb,";");
PREPARE database_create FROM @database_create;
EXECUTE database_create;
DEALLOCATE PREPARE database_create;
WHILE @loop_num<>@counter DO
SET @loop_num=@loop_num+1;
SET @rownumber=0; # Row Number
SET @tbl='';
SELECT
v.value
INTO @tbl
FROM (SELECT
TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(t.value, ',', n.n), ',', -1)) AS value,
@rownumber:=@rownumber+1 AS rownumber
FROM (SELECT @tbls AS value) AS t
CROSS JOIN (SELECT a.N + b.N * 10 + 1 n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
ORDER BY n
) n
WHERE n.n <= 1 + (LENGTH(t.value) - LENGTH(REPLACE(t.value, ',', '')))
HAVING rownumber=@loop_num) AS v;
# Creating Table
SET @drop_table=CONCAT(" DROP TABLE IF EXISTS ",@repldb,".",@tbl,";");
SET @create_table=CONCAT(" CREATE TABLE ",@repldb,".",@tbl," LIKE ",@masterdb,".",@tbl,";");
# Preparing STMT for @drop_table
PREPARE droptable FROM @drop_table;
EXECUTE droptable;
DEALLOCATE PREPARE droptable;
# Preparing STMT for @create_table
PREPARE create_table FROM @create_table;
EXECUTE create_table;
DEALLOCATE PREPARE create_table;
END WHILE;
END IF;
END
@counter
、,
の出現回数(tables delimiter)。iNewDB
とiOldDB
がnullまたは空でない場合は、続行します。iTables
パラメータの入力数を使用して新しいテーブルを作成します。mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| test_old |
+--------------------+
5 rows in set (0.00 sec)
mysql> SHOW TABLES IN test_old;
+--------------------+
| Tables_in_test_old |
+--------------------+
| test1 |
| test2 |
| test3 |
| test4 |
+--------------------+
4 rows in set (0.00 sec)
mysql>
mysql> CALL test.spCreateRplDB(
-> 'test_dev', # New DB
-> 'test_old', # Master DB
-> 'test1,test2,test4');
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| test_dev |
| test_old |
+--------------------+
6 rows in set (0.00 sec)
mysql> SHOW TABLES IN test_dev;
+--------------------+
| Tables_in_test_dev |
+--------------------+
| test1 |
| test2 |
| test4 |
+--------------------+
3 rows in set (0.00 sec)
mysql>