如果存在则更改表或如果不存在则创建

时间:2013-05-30 13:10:35

标签: mysql alter-table create-table

我需要运行一个也可以作为更新程序的安装程序。 安装程序需要能够最终拥有mysql数据库的某个方案/结构,无论是否存在某些表,错过了几列,或者由于其结构是最新的而无需更改。

如何优雅地组合ALTERCREATE

我当时认为必须有“添加...如果...重复”

假设我有表A.在一个客户端中,表有一列-A1,另一个客户端具有相同的表,但列A1和列A2。

我希望我的sql命令使两个客户端的表A保持三列:A1,A2和A3。

同样,我的脚本是一个我转储到mysql的sql文件。

我该怎么办?谢谢: - )

3 个答案:

答案 0 :(得分:20)

MySQL INFORMATION_SCHEMA数据库救援:

-- First check if the table exists
IF EXISTS(SELECT table_name 
            FROM INFORMATION_SCHEMA.TABLES
           WHERE table_schema = 'db_name'
             AND table_name LIKE 'wild')

-- If exists, retreive columns information from that table
THEN
   SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT
     FROM INFORMATION_SCHEMA.COLUMNS
    WHERE table_name = 'tbl_name'
      AND table_schema = 'db_name';

   -- do some action, i.e. ALTER TABLE if some columns are missing 
   ALTER TABLE ...

-- Table does not exist, create a new table
ELSE
   CREATE TABLE ....

END IF;

更多信息:

<强>更新

另一个可能更简单的选择是删除现有表并使用新架构重新创建它。为此,您需要:

  1. 创建临时表,即现有表的精确副本
  2. 使用旧表中的数据填充临时表
  3. 放下旧桌子
  4. 使用新架构创建新表
  5. 使用临时表中的信息填充新表
  6. 删除临时表。
  7. 所以,在SQL代码中:

    CREATE TABLE old_table_copy LIKE old_table;
    
    INSERT INTO old_table_copy
    SELECT * FROM old_table;
    
    DROP TABLE old_table;
    
    CREATE TABLE new_table (...new values...);
    
    INSERT INTO new_table ([... column names from old table ...])
    SELECT [...column names from old table ...] 
    FROM old_table_copy;
    
    DROP TABLE old_table_copy;
    

    实际上最后一步,“删除临时表。”,你可以跳过一段时间。为了以防万一,您可能希望对旧表进行某种备份,“只是在案例中”。

    更多信息:

答案 1 :(得分:1)

如果您使用的是编码语言,请执行以下操作:

SHOW TABLES LIKE 'myTable'

如果返回值调用,则alter else调用create

答案 2 :(得分:0)

虽然这个话题已经有几年了,但我一直在寻找类似问题的解决方案。关于@GregD 的回答,我找到了一个适合我的解决方案。 SQL 脚本创建表,但是,如果数据库中已有表,则应应用更改。在这个版本中,它只有在有额外的列时才有效。修改后的(剩余)列不起作用。

-- We create a procedure that is dropped if it exists already.
DROP PROCEDURE IF EXISTS changeFunction;
-- We have to change the delimiter for the procedure.
DELIMITER $$
CREATE PROCEDURE changeFunction()
    BEGIN
-- Check if table already exists
IF EXISTS(SELECT table_name 
            FROM INFORMATION_SCHEMA.TABLES
           WHERE table_schema = 'your_database_name'
             AND table_name LIKE 'your_table_name')

-- It exists, so create a new table and copy the data.
THEN
    -- Copy the data into a copy of the table.
    CREATE TABLE `your_table_name_copy` LIKE `your_table_name`;
    INSERT INTO `your_table_name_copy` SELECT * FROM `your_table_name`;
    -- Remove old table
    DROP TABLE `your_table_name`;
    -- Create the new table
    CREATE TABLE IF NOT EXISTS `your_table_name` (
        -- Your columns
    );
    -- Copy values, it determines the old column names by itself
    SET @v1 := (SELECT GROUP_CONCAT(COLUMN_NAME)
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_SCHEMA = 'your_database_name' AND TABLE_NAME = 'your_table_name_copy');
    -- Since the columns are detected automatically, we have to execute the 
    -- statement as prepared statement.
    SET @q1 := CONCAT('INSERT INTO `your_table_name` (', @v1, ') ',
                      'SELECT ', @v1, ' FROM `your_table_name_copy`');
    PREPARE stmt FROM @q1;
    EXECUTE stmt;
    -- Remove copy
    DROP TABLE `your_table_name_copy`;
ELSE
    -- It does not exist, simply create it
    CREATE TABLE IF NOT EXISTS `your_table_name` (
        -- Your columns
    );
END IF;
END $$
-- Reset the delimiter
DELIMITER ;
-- Call the function
CALL changeFunction();