Determining if MySQL table index exists before creating

前端 未结 7 1758
一向
一向 2021-02-04 14:35

Our system\'s automated database migration process involves running .sql scripts containing new table definitions and their accompanying indexes.

I require the ability t

相关标签:
7条回答
  • 2021-02-04 15:13

    Since Text and Blobs need a size, I added it to the stored procedure.

    DROP PROCEDURE IF EXISTS createIndex;
    
    DELIMITER $$
    -- Create a temporary stored procedure for checking if Indexes exist before attempting to re-create them. => can be called
    $$
    CREATE PROCEDURE `createIndex`(
        IN `tableName` VARCHAR(128),
        IN `indexName` VARCHAR(128),
        IN `indexColumns` VARCHAR(128),
        IN `indexSize` VARCHAR(128)
    )
    BEGIN
      IF((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() AND table_name = tableName AND index_name = indexName)  = 0) THEN
            IF(indexSize > 0) THEN
                SET @sqlCommand = CONCAT('CREATE INDEX ' , indexName , ' ON ' , tableName, '(', indexColumns, '(' , indexSize, '))');
            ELSE
                SET @sqlCommand = CONCAT('CREATE INDEX ' , indexName , ' ON ' , tableName, '(', indexColumns, ')');
            END IF;
        PREPARE _preparedStatement FROM @sqlCommand;
        EXECUTE _preparedStatement;
      END IF;
    END $$
    DELIMITER ;
    
    0 讨论(0)
  • 2021-02-04 15:15
    SELECT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE
    `TABLE_CATALOG` = 'def' AND `TABLE_SCHEMA` = DATABASE() AND
    `TABLE_NAME` = theTable AND `INDEX_NAME` = theIndexName
    
    0 讨论(0)
  • 2021-02-04 15:19

    You can query infomration_schema database for this and many more useful information

    http://dev.mysql.com/doc/refman/5.0/en/information-schema.html

    0 讨论(0)
  • 2021-02-04 15:19

    Not a new version but a more complete solution that includes a call to create 2 indexes.

    USE MyDatabaseName;
    DELIMITER $$
    -- Create a temporary stored procedure for checking if Indexes exist before attempting to re-create them.
    DROP PROCEDURE IF EXISTS `MyDatabaseName`.`spCreateIndex` $$
    CREATE PROCEDURE `MyDatabaseName`.`spCreateIndex` (tableName VARCHAR(128), in indexName VARCHAR(128), in indexColumns VARCHAR(128))
    BEGIN
      IF((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() AND table_name = tableName AND index_name = indexName)  = 0) THEN
        SET @sqlCommand = CONCAT('CREATE INDEX ' , indexName , ' ON ' , tableName, '(', indexColumns, ')');
        PREPARE _preparedStatement FROM @sqlCommand;
        EXECUTE _preparedStatement;
      END IF;
    END $$
    DELIMITER ;
    
    -- Create the Indexes if they do not exist already.
    CALL spCreateIndex('MyCustomers', 'idxCustNum', 'CustomerNumber');
    CALL spCreateIndex('MyProducts', 'idxProductName', 'ProductName');
    
    DELIMITER $$
    -- Drop the temporary stored procedure.
    DROP PROCEDURE IF EXISTS `MyDatabaseName`.`spCreateIndex` $$
    DELIMITER ;
    
    0 讨论(0)
  • 2021-02-04 15:25

    You could just create another table with the correct indices, copy everything from the old table and then drop it and rename the new table back to what the old one used to be. A bit hackish and might be a bit heavy for big tables but still fairly straightforward.

    0 讨论(0)
  • 2021-02-04 15:28

    After some more banging my head off the wall and intense googling I found the information_schema.statistics table. This contains the index_name for a table.

    My stored procedure is now

    DELIMITER $$
    
    DROP PROCEDURE IF EXISTS csi_add_index $$
    CREATE PROCEDURE csi_add_index(in theTable varchar(128), in theIndexName varchar(128), in theIndexColumns varchar(128)  )
    BEGIN
     IF((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name =
    theTable AND index_name = theIndexName)  = 0) THEN
       SET @s = CONCAT('CREATE INDEX ' , theIndexName , ' ON ' , theTable, '(', theIndexColumns, ')');
       PREPARE stmt FROM @s;
       EXECUTE stmt;
     END IF;
    END $$
    

    and works as expected.

    Thanks for the suggestions.

    0 讨论(0)
提交回复
热议问题