it-swarm.com.de

Durch Komma getrennte Werte durchlaufen

Ich habe eine Master-DB. Ich möchte eine doppelte Datenbank der Master-Datenbank erstellen, aber nicht alle Tabellen, die gerade angegeben wurden.

Ich habe diese Tabellennamen in durch Kommas getrennten Zeichenfolgen. tbl1, tbl2, tbl7, tbl10 usw.

Ich versuche, eine gespeicherte Prozedur zu erstellen, die sie übergibt new DB name Dadurch wird die Datenbank erstellt und die angegebene Tabelle darauf repliziert. Bisher habe ich zwei Dinge, aber ich weiß nicht, wie ich sie durchlaufen soll. Ich bin neu bei DB. Bitte führen Sie, wie dies erreicht werden kann.

(Hinweis) Ich habe nicht gefunden, ob ein Array zum Durchlaufen verwendet werden kann. Die Tabellennamen könnten auch in einer Arrayvariablen gespeichert werden, da die Tabellennamen sind fest codiert.

Das Folgende ist der Sudo-Code, den ich wünsche.

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
5
Bsienn

Hier sind die Schritte zum Layout in der gespeicherten Prozedur

  • Erstellen Sie die Zieldatenbank
  • Bestimmen Sie, wie viele Elemente in der Liste der Tabellen enthalten sind
  • Durchlaufen Sie jedes Element der Tabellenliste mit der Funktion ELT ()
  • Nehmen Sie jedes Element und bilden Sie eine SQL-Anweisung, um die neue Tabelle in der Ziel-DB zu erstellen

Hier ist diese gespeicherte Prozedur

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 ;
7
RolandoMySQLDBA

@ RolandoMySQLDBA poste es zuerst, aber ich habe einen anderen Weg.

Mit dieser Option durch Komma getrennte Zeichenfolge getrennt und dies für die Anzahl der Vorkommen habe ich diese gespeicherte Prozedur erstellt:

GESPEICHERTE PROZEDUR:

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 @[email protected]+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 @[email protected]_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:[email protected]+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 [email protected]_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

PROZESSE:

  1. @counter, Anzahl der Vorkommen von , ( Tabellenbegrenzer ).
  2. Wenn es mehr als 0 Vorkommen gibt und iNewDB und iOldDB nicht null oder leer sind, fahren Sie fort.
  3. Erstellen Sie die neue Datenbank ( iNewDB ).
  4. Erstellen neuer Tabellen mit der Anzahl der Eingaben im Parameter iTables.

PRÜFUNG:

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> 
2
oNare