3

I work with a database that has hundreds of tables with the very same structure and an identical syntax. Everyday more tables are created, thus the database is continuously growing. To dynamically append this growing amount of tables I use a MySQL procedure which works just fine.

Yet once appended I cannot identify the origin of the rows, since the tables don´t contain any information to be distinguished. Hence I would like to integrate a MySQL statement in the following procedure to automatically get the TABLE_NAME from the information_schema and set is as a value in the corresponding table. I already created a column for that, but struggle with the adjustment of the procedure. I would really appreciate any help or suggestion to solve this.

CREATE PROCEDURE getallarbeitsplaene(recordOffset INT, recordCount INT)

BEGIN
    DECLARE tableName VARCHAR(255);
    DECLARE endOfTables INT DEFAULT 0;

    DECLARE cur CURSOR FOR
        SELECT t.table_name
        FROM information_schema.tables t
        WHERE t.table_schema = DATABASE()
          AND t.table_type='BASE TABLE'
                        AND    NOT table_name LIKE '%x_arbeitsplan'
                        AND table_name LIKE '%_arbeitsplan';

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET endOfTables = 1;

    DROP TEMPORARY TABLE IF EXISTS alle_plaene;

    CREATE TEMPORARY TABLE alle_plaene (
        `ID` INT(11) NOT NULL,
        `AP` VARCHAR(8) NOT NULL,
                    `Name` VARCHAR(128) NOT NULL,
                    `Baugruppentyp` VARCHAR(128) NOT NULL,
                    `Basiseinheit` VARCHAR(8) NOT NULL,
                    `Zeit_Basiseinheit` NUMERIC(10,0) NOT NULL,
                    `vor_OF` BINARY(1) NOT NULL,
                    `zwischen_OF` BINARY(1) NOT NULL,
                    `nach_OF` BINARY(1) NOT NULL,
                    `Annahme_Grundlage` VARCHAR(64) NOT NULL,
                    `Budget_AG_Bankraum` VARCHAR(7) NOT NULL,
                    `Budget_AG_FU` VARCHAR(7) NOT NULL,
                    `Datum_voraus` DATE,
                    `Budget_voraus` INT(11) NOT NULL
                    ) ENGINE=MEMORY;

    OPEN cur;

    tablesLoop: LOOP
        FETCH cur INTO tableName;

        IF endOfTables = 1 THEN
            LEAVE tablesLoop;
        END IF;

        SET @s = CONCAT('INSERT INTO alle_plaene (Name, Baugruppentyp, Basiseinheit, Zeit_Basiseinheit, vor_OF, zwischen_OF, nach_OF, Annahme_Grundlage, Budget_AG_Bankraum, Budget_AG_FU, Datum_voraus, Budget_voraus) SELECT `Name`, `Baugruppentyp`, `Basiseinheit`, `Zeit_Basiseinheit`, `vor_OF`, `zwischen_OF`, `nach_OF`, `Annahme_Grundlage`, `Budget_AG_Bankraum`, `Budget_AG_FU`, `Datum_voraus`, `Budget_voraus`   FROM ', tableName, ' ORDER BY ID DESC');
        PREPARE stmt FROM @s;
        EXECUTE stmt;

    END LOOP;

    CLOSE cur;

    SELECT `Name`, `Baugruppentyp`, `Basiseinheit`, `Zeit_Basiseinheit`, `vor_OF`, `zwischen_OF`, `nach_OF`, `Annahme_Grundlage`, `Budget_AG_Bankraum`, `Budget_AG_FU`, `Datum_voraus`, `Budget_voraus` FROM alle_plaene;

END 
CKE
  • 1,533
  • 19
  • 18
  • 29
Tobi Z
  • 31
  • 1

1 Answers1

0

This should work

    DELIMITER //

    DROP PROCEDURE IF EXISTS getallarbeitsplaene //
    CREATE PROCEDURE getallarbeitsplaene()
    BEGIN
        DECLARE tableName VARCHAR(64);
        DECLARE endOfTables INT DEFAULT 0;

        DECLARE cur CURSOR FOR
            SELECT t.table_name
            FROM information_schema.tables t
            WHERE t.table_schema = DATABASE()
              AND t.table_type='BASE TABLE'
              AND NOT table_name LIKE '%x_arbeitsplan'
              AND table_name LIKE '%_arbeitsplan';

        DECLARE CONTINUE HANDLER FOR NOT FOUND SET endOfTables = 1;

        DROP TEMPORARY TABLE IF EXISTS alle_plaene;

        CREATE TEMPORARY TABLE alle_plaene (
          `ID` INT(11) NOT NULL,
          `AP` VARCHAR(8) NOT NULL,
          `Name` VARCHAR(128) NOT NULL,
          `Baugruppentyp` VARCHAR(128) NOT NULL,
          `Basiseinheit` VARCHAR(8) NOT NULL,
          `Zeit_Basiseinheit` NUMERIC(10,0) NOT NULL,
          `vor_OF` BINARY(1) NOT NULL,
          `zwischen_OF` BINARY(1) NOT NULL,
          `nach_OF` BINARY(1) NOT NULL,
          `Annahme_Grundlage` VARCHAR(64) NOT NULL,
          `Budget_AG_Bankraum` VARCHAR(7) NOT NULL,
          `Budget_AG_FU` VARCHAR(7) NOT NULL,
          `Datum_voraus` DATE,
          `Budget_voraus` INT(11) NOT NULL,
          `tableName` VARCHAR(64) NOT NULL
        ) ENGINE=MEMORY;

        OPEN cur;

        tablesLoop: LOOP
          FETCH cur INTO tableName;

          IF endOfTables = 1 THEN
            LEAVE tablesLoop;
          END IF;

          SET @s = CONCAT('INSERT INTO alle_plaene (ID, AP, Name, Baugruppentyp, Basiseinheit, Zeit_Basiseinheit, vor_OF, zwischen_OF, nach_OF, Annahme_Grundlage, Budget_AG_Bankraum, Budget_AG_FU, Datum_voraus, Budget_voraus, tableName)  SELECT `ID`, `AP`, `Name`, `Baugruppentyp`, `Basiseinheit`, `Zeit_Basiseinheit`, `vor_OF`, `zwischen_OF`, `nach_OF`, `Annahme_Grundlage`, `Budget_AG_Bankraum`, `Budget_AG_FU`, `Datum_voraus`, `Budget_voraus`, ''', tableName, ''' FROM `', tableName, '` ORDER BY ID DESC');
          PREPARE stmt FROM @s;
          EXECUTE stmt;
          DEALLOCATE PREPARE stmt;
        END LOOP;

        CLOSE cur;

        SELECT * FROM alle_plaene;

    END //

DELIMITER ;

call getallarbeitsplaene();

This solution deviates from your version in only a couple of places but here are some points for you to consider

information_schema.table_name is VARCHAR(64).

You don't use either input parameter in your code, so I've dropped them.

You should add the table_name into the temporary table and populate the column with a quoted string within the @s = CONCAT(...) statement.

The ID and AP columns need to be populated in the temp table or dropped entirely, you have them as NOT NULL so they must get a value.

I can't help but wonder why you are creating multiple identical tables each day just to combine the output in a temp table to query altogether, surely a single table solution would be better here.

Paul Campbell
  • 1,906
  • 2
  • 12
  • 19
  • Thank you very much for your quick help and advice - i appreciate that. For some reason i missed to add the column and populate it within the CONCAT(...) statement. Now it works as it is supposed to. Regarding your comment on creating more and more tables i absolutely agree that this is not ideal and i will soon look into that. – Tobi Z Jul 11 '18 at 09:12