如何从存储过程创建索引或在MySQL中的每个表上创建索引?

时间:2013-06-22 00:19:06

标签: mysql sql stored-procedures indexing

这是我迄今为止尝试过的两件事,以及他们的错误消息:

DELIMITER //

CREATE PROCEDURE createModifiedIndex(t varchar(256))
  BEGIN
    declare idx varchar(256);
    DECLARE i int;
    declare makeIndexSql varchar(256);
    set idx = concat('idx_', t, '_modified_on');
    set i = (select count(*) from INFORMATION_SCHEMA.STATISTICS where table_name = t and index_name = idx);
    if i > 0 then
        set makeIndexSql = concat('create index ', idx, ' on ', t, ' (modified_on);');
        prepare stmt from makeIndexSql;
        execute stmt;
    end if;
  END //

DELIMITER ;

call createModifiedIndex ('ACHDebitFrequencies');
call createModifiedIndex ...
  

第5行的错误1064(42000):您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以便在'makeIndexSql附近使用正确的语法;                   执行stmt;           万一;     结束'第10行

这是另一种不同的尝试,但不起作用,因为MySQL不允许存储过程之外的IF / THEN。

set @i = (select count(*) from INFORMATION_SCHEMA.STATISTICS where table_name = 'ACHDebitFrequencies' and index_name = 'idx_ACHDebitFrequencies_modified_on');
if @i > 0 then begin
        create index 'idx_ACHDebitFrequencies_modified_on' on ACHDebitFrequencies (modified_on);
end;
end if;
...
  

第3行的错误1064(42000):您的SQL语法出错;检查与您的MySQL服务器版本对应的手册,以便在'if @i>附近使用正确的语法。 0然后开始           在第1行的ACHD'创建索引'idx_ACHDebitFrequencies_modified_on'

版本mysql-5.1.62-r1

1 个答案:

答案 0 :(得分:1)

您的过程的核心问题是PREPARE语句仅适用于用户变量或字符串文字。它无法从过程变量中准备语句。

  

<强> PREPARE Syntax
  PREPARE stmt_name FROM preparable_stmt
  ... preparable_stmt是字符串文字或用户变量   包含SQL语句的文本。

DELIMITER //
CREATE PROCEDURE createModifiedIndex(t VARCHAR(256))
  BEGIN
    DECLARE idx VARCHAR(256);
    DECLARE i INT;

    SET idx = CONCAT('idx_', t, '_modified_on');
    SET i = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name = t AND index_name = idx);
    IF i = 0 THEN
        SET @makeIndexSql = CONCAT('CREATE INDEX ', idx, ' ON ', t, ' (modified_on);');
        PREPARE stmt FROM @makeIndexSql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt; -- Use DEALLOCATE when you're done with the statement
    END IF;
  END //

DELIMITER ;