我们可以在没有创建过程的情况下在mysql中运行代码

时间:2014-11-13 15:35:48

标签: mysql transactions

我想为我的dba创建一个sql文件,用于检查表中是否存在索引。 IF不存在 - 创建它。 我发现了很多使用存储过程的例子,但我只想运行一次。

这样的事情:

-- Creates an index if it does not already exist in MySQL.
START TRANSACTION;
SET IndexIsThere = 0;
SET given_table = 'IDR_CHGS';
SET given_index = 'FK_IDR_PATIENT_PT_ID_idx1';


SELECT COUNT(1) INTO IndexIsThere
FROM INFORMATION_SCHEMA.STATISTICS
WHERE  table_name  = given_table
    AND index_name  = given_index;

    IF IndexIsThere = 0 THEN
        SET @sqlstmt = CONCAT('CREATE INDEX ',given_index,' ON ', given_database,'.',given_table,' (',given_columns,')');
        PREPARE st FROM @sqlstmt;
        EXECUTE st;
        DEALLOCATE PREPARE st;
        SELECT CONCAT('Created index ', given_table,'.', given_index, ' on columns ', given_columns) AS 'CreateIndex status';
    ELSE
        SELECT CONCAT('Index ', given_index,' Already Exists on Table ', given_database,'.',given_table) AS 'CreateIndex status';
    END IF;

COMMIT;

这可行吗?

1 个答案:

答案 0 :(得分:1)

MySQL不支持存储的例程或触发器之外的IF / THEN / ELSE结构。

如果您使用PREPARE和EXECUTE,如果没有索引,您可以简单地形成一个包含CREATE INDEX语句的字符串,如果没有,则可以形成一个no-op语句(例如注释)。

SELECT COALESCE(CONCAT('SELECT \'index ', S.INDEX_NAME, ' exists already\''), 
    'CREATE INDEX `idx_x` ON test.foo (`x`)') INTO @sql
FROM (SELECT NULL) AS d
LEFT OUTER JOIN INFORMATION_SCHEMA.STATISTICS AS S
 ON (S.TABLE_SCHEMA, S.TABLE_NAME, S.INDEX_NAME) = ('test', 'foo', 'idx_x');

PREPARE s from @sql;
EXECUTE s;

如果索引存在,@sql将是:

mysql> select @sql;
+-------------------------------------+
| @sql                                |
+-------------------------------------+
| SELECT 'index idx_x exists already' |
+-------------------------------------+

如果索引不存在,@sql将为:

mysql> select @sql;
+----------------------------------------+
| @sql                                   |
+----------------------------------------+
| CREATE INDEX `idx_x` ON test.foo (`x`) |
+----------------------------------------+

顺便说一句,所有CREATE和ALTER语句都在语句之前和之后隐式提交,因此没有任何意图使用启动事务和提交方式。见http://dev.mysql.com/doc/refman/5.6/en/implicit-commit.html