当动态更改其中的表时,Mysql调用过程失败

时间:2017-06-10 05:37:32

标签: mysql procedure

我想根据表是否具有特定列来动态更改表。

我的数据库名称为summer_cms,其中有超过50个表。

我想要的是:

  1. 如果某个表中有一个名为add_time的列,那么我想在其中添加一列add_user_id
  2. 同样,如果找到update_user_id,我想在表格中添加update_time
  3. 我知道我应该在创建数据库模式的过程中将其删除,但我的数据库已经构建完毕,我必须根据需要对其进行更改。

    所以我创建了一个程序来执行它:

    CREATE PROCEDURE ALTER_SUMMER_TABLE()
    BEGIN
        DECLARE tableName VARCHAR(64);
        DECLARE exitence VARCHAR(64);
    
        DECLARE ntable INT;    # number of tables
        DECLARE i INT;         # index
        SET i = 0;
    
        # get the count of table
        SELECT COUNT(DISTINCT(TABLE_NAME)) INTO ntable FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'summer_cms';
    
        WHILE i < ntable DO
            # select the specific table name into the variable of `tableName`.
            SELECT TABLE_NAME INTO tableName
            FROM information_schema.COLUMNS
            WHERE TABLE_SCHEMA = 'summer_cms'
            AND COLUMN_NAME = 'add_time'
            LIMIT 1 OFFSET i;
    
            # alter table, but I get error in this clause.
            ALTER TABLE tableName ADD COLUMN `add_user_id` INT NOT NULL DEFAULT 0 COMMENT 'add user id';
    
            # check if the table has `update_time`
            SELECT TABLE_NAME INTO exitence
            FROM information_schema.COLUMNS
            WHERE TABLE_SCHEMA = 'summer_cms'
            AND TABLE_NAME = tableName
            AND COLUMN_NAME = 'update_time';
    
            # add `update_user_id` if `update_time` be found.
            IF exitence THEN
                ALTER TABLE tableName ADD COLUMN `update_user_id` INT NOT NULL DEFAULT 0 COMMENT 'update user id';
            END IF;
            SET i = i + 1;
        END WHILE;
    END
    

    但是当我调用此程序时出现错误。

    Procedure execution failed
    1146 - Table 'summer_cms.tableName' doesn't exist
    

    任何人都可以告诉我我错过了什么或错了什么?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您可以对您的程序进行一些更改,以使其更加简化以及解决一些问题。

首先使用光标选择表名而不是使用两个选择你的使用。其次,使用预准备语句,允许您动态设置表名...

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `ALTER_SUMMER_TABLE`()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE tableName VARCHAR(64);
    declare cur cursor for SELECT TABLE_NAME
                             FROM information_schema.COLUMNS
                            WHERE TABLE_SCHEMA = 'summer_cms'
                            AND COLUMN_NAME = 'add_time';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    open cur;

    start_loop: loop
        fetch cur into tableName;
        if (done = 1 )THEN
             LEAVE start_loop;
        END IF;
        SET @sql = CONCAT('ALTER TABLE ', tableName,' ADD COLUMN `add_user_id` INT NOT NULL DEFAULT 0 ');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;

    end loop;

    close cur;
END$$
DELIMITER ;

您可以进行一些调整 - 仅提取表格中没有列的表名称。

答案 1 :(得分:1)

这是动态sql的一个例子

drop procedure if exists alter_table;
delimiter //

CREATE DEFINER=`root`@`localhost`  procedure alter_table()

begin
declare tablename varchar(20);
set tablename = 'u';

set @sqlstmt =  concat('ALTER TABLE ', tableName, ' ADD COLUMN ', char(96), 'add_user_id', char(96), ' INT NOT NULL DEFAULT 0 COMMENT', char(39), 'add user id', char(39),';');
prepare stmt from @sqlstmt;
execute stmt;
deallocate prepare stmt;

end //

delimiter ;

注意我使用了ascii反引号和单引号。