2013-10-31 83 views
1

我對此很陌生,所以我會盡力解釋。我在表中有一個UNIQUE鍵,我希望通過添加另一列來改變它。mysql - 修改唯一密鑰

所以,我有一個UNIQUE鍵 - UNIQUE_tablename_column1_column2。我的目標是放棄此密鑰並創建一個名爲 - UNIQUE_tablename_column1_column2_column3的新密鑰。另外,如果需要的話,我正在尋求確保這可以一遍又一遍地運行。

我把基本的sql下來了,ALTER TABLE tablename DROP index UNIQUE_tablename_column1_column2,將drop掉原來的key。然後ALTER TABLE tablename ADD CONSTRAINT UNIQUE_tablename_column1_column2_column3 UNIQUE (column1,column2,column3)將添加我需要的新。

我想要做的就是把它放在某種IF/IF EXISTS THEN語句中,其中IF EXISTS UNIQUE_tablename_column1_column2然後DROP UNIQUE_tablename_column1_column2和ADD UNIQUE_tablename_column1_column2_column3。

任何想法,幫助和援助非常感謝。 謝謝!

回答

2

簡短的回答是,您需要在存儲過程中編寫這樣的邏輯,因爲IF/ELSE結構只能在存儲的程序中工作。

下面是我經常使用的兩個示例腳本來刪除和創建索引,首先檢查是否存在。它支持任何類型的索引(唯一或非唯一)。

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

我很欣賞的響應。我將不得不嘗試並報告! – Dubl1n