【问题标题】:Insert individual table_name as column value in all tables在所有表中插入单个 table_name 作为列值
【发布时间】:2018-07-10 06:08:38
【问题描述】:

我使用的数据库包含数百个具有相同结构和相同语法的表。每天都会创建更多的表,因此数据库也在不断增长。为了动态追加越来越多的表,我使用了MySQL 过程,它工作得很好。

然而,一旦添加,我就无法识别行的来源,因为这些表不包含任何要区分的信息。因此,我想在以下过程中集成MySQL 语句,以自动从information_schema 中获取TABLE_NAME,并将其设置为相应表中的值。我已经为此创建了一个专栏,但在调整程序时遇到了困难。我真的很感激任何帮助或建议来解决这个问题。

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 

【问题讨论】:

    标签: mysql procedure information-schema tablename


    【解决方案1】:

    这应该可行

        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();
    

    此解决方案仅在几个地方与您的版本有所不同,但您需要考虑以下几点

    information_schema.table_name 是 VARCHAR(64)。

    您的代码中没有使用任何一个输入参数,所以我已经删除了它们。

    您应该将 table_name 添加到临时表中,并在 @s = CONCAT(...) 语句中使用带引号的字符串填充列。

    IDAP 列需要填充到临时表中或完全删除,您将它们设置为 NOT NULL,因此它们必须获得一个值。

    我不禁想知道为什么您每天都创建多个相同的表只是为了将临时表中的输出组合在一起进行查询,当然单表解决方案在这里会更好。

    【讨论】:

    • 非常感谢您的快速帮助和建议 - 我很感激。由于某种原因,我错过了添加列并将其填充到 CONCAT(...) 语句中。现在它按预期工作。关于您对创建越来越多的表的评论,我绝对同意这并不理想,我将很快研究。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2016-05-27
    相关资源
    最近更新 更多