我想为我的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;
这可行吗?
答案 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