1

私はこれに慣れていないので、できる限り説明しようとします。別の列を追加して変更しようとしているテーブルに UNIQUE キーがあります。

したがって、UNIQUE キー - UNIQUE_tablename_column1_column2 があります。私の目標は、このキーを削除して、UNIQUE_tablename_column1_column2_column3 という名前の新しいキーを作成することです。また、必要に応じてこれを何度も実行できるようにしています。

基本的な sql がダウンしてALTER TABLE tablename DROP index UNIQUE_tablename_column1_column2います。元のキーをドロップします。そして、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.

どんなアイデア、助け、援助も大歓迎です。ありがとう!

4

1 に答える 1

2

簡単に言えば、IF/ELSE 構造はストアド プログラムでのみ機能するため、このようなロジックはストアド プロシージャに記述する必要があります。

以下に、インデックスの削除と作成に定期的に使用する 2 つのスクリプト例を示します。最初に存在を確認します。あらゆる種類のインデックス (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());
于 2013-10-31T18:36:32.720 に答える