mysql - 更改唯一键

时间:2013-10-31 17:50:07

标签: mysql

我是新手,所以我会尽力解释。我在表中有一个UNIQUE键,我希望通过添加另一列来改变它。

所以,我有一个UNIQUE键 - UNIQUE_tablename_column1_column2。我的目标是DROP这个键并创建一个名为UNIQUE_tablename_column1_column2_column3的新键。此外,我希望确保在需要时可以反复运行。

我有基本的sql down ALTER TABLE tablename DROP index UNIQUE_tablename_column1_column2,将DROP原始密钥。然后ALTER TABLE tablename ADD CONSTRAINT UNIQUE_tablename_column1_column2_column3 UNIQUE (column1,column2,column3)将添加我需要的新内容。

我想做的是把它放在某种IF / IF EXISTS THEN语句中,其中IF EXISTS UNIQUE_tablename_column1_column2 THEN DROP UNIQUE_tablename_column1_column2 AND ADD UNIQUE_tablename_column1_column2_column3。

非常感谢任何想法,帮助和帮助。 谢谢!

1 个答案:

答案 0 :(得分:2)

简短的回答是,您需要在存储过程中编写这样的逻辑,因为IF / ELSE结构仅适用于存储的程序。

以下是我经常使用的两个示例脚本,用于删除和创建索引,首先检查是否存在。它支持任何类型的索引(UNIQUE或非唯一)。

-- Use to create indexes via a CALL statement. Be sure to use DELIMITER when creating these
-- procedures on your system:

    CREATE PROCEDURE `admin_create_index`(
        index_name VARCHAR(64),    
        column_list VARCHAR(64),   
        table_name VARCHAR(64),
        is_unique TINYINT(1),
        db_name  VARCHAR(64)
    )
    BEGIN
    SET @sqlexec := 
    CONCAT
    (
        'SELECT @i := COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME = \'',
        index_name, 
        '\' AND TABLE_NAME = \'', 
        table_name,
        '\' AND TABLE_SCHEMA = \'',
        db_name,
        '\''
    );

    SELECT CONCAT('Executing: "', @sqlexec, '"') AS 'Info';
    PREPARE lookup FROM @sqlexec;
    EXECUTE lookup;
    DEALLOCATE PREPARE lookup;

    IF @i = 0 THEN
        SET @sqlexec := CONCAT('CREATE ', IF(is_unique > 0, 'UNIQUE ', ''), 'INDEX ', index_name, ' ON `', db_name, '`.`', table_name, '`(', column_list, ')');
        SELECT CONCAT('Executing: "', @sqlexec, '"') AS 'Info';
        PREPARE statement FROM @sqlexec;
        EXECUTE statement;
        DEALLOCATE PREPARE statement;
        SELECT CONCAT('Successful execution of: "', @sqlexec, '"') AS 'Info';
    ELSE
        SELECT CONCAT('Warning: Index `', index_name, '` already exists on `', db_name, '`.`', table_name, '`') AS 'Warning';
    END IF;
    END;

-- Use to drop an index (if it exists):

CREATE PROCEDURE `admin_drop_index`(
    index_name VARCHAR(64),    
    table_name VARCHAR(64),
    db_name  VARCHAR(64)
)
BEGIN
SET @sqlexec := 
CONCAT
(
    'SELECT @i := COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME = \'',
    index_name, 
    '\' AND TABLE_NAME = \'', 
    table_name,
    '\' AND TABLE_SCHEMA = \'',
    db_name,
    '\''
);

SELECT CONCAT('Executing: "', @sqlexec, '"') AS 'Info';
PREPARE lookup FROM @sqlexec;
EXECUTE lookup;
DEALLOCATE PREPARE lookup;

IF @i > 0 THEN
    SET @sqlexec := CONCAT('ALTER TABLE `', db_name, '`.`', table_name, '` DROP INDEX `', index_name, '`');
    SELECT CONCAT('Executing: "', @sqlexec, '"') AS 'Info';
    PREPARE statement FROM @sqlexec;
    EXECUTE statement;
    DEALLOCATE PREPARE statement;
    SELECT CONCAT('Successful execution of: "', @sqlexec, '"') AS 'Info';
ELSE
    SELECT CONCAT('Warning: Index `', index_name, '` does not exist on `', db_name, '`.`', table_name, '`') AS 'Warning';
END IF;

END;

以下是CALL语句示例:

CALL admin_create_index('my_index_name', 'col_name_a, col_name_b', 'table_name', TRUE, DATABASE());

CALL admin_drop_index('my_index_name', 'table_name', DATABASE());