Ошибка при создании индекса для таблицы Mysql - PullRequest
0 голосов
/ 26 сентября 2019

Я работаю над созданием индекса для таблицы с MySQL.
У меня есть 2 таблицы:
1. account
enter image description here
2. x_activity (x - это account_id, связанный с таблицей "account", например: 1_activity, 2_activity).enter image description here
Итак, я создал «Индекс» для таблицы активности:
Вот мой код:

DROP PROCEDURE if exists update_index_for_table;
DELIMITER $$
CREATE PROCEDURE update_index_for_table()
BEGIN

  DECLARE done INT DEFAULT FALSE;
  DECLARE accountid INT;  
  --
  -- GET ALL ACCOUNT ID
  --

  DECLARE accountids CURSOR FOR SELECT account_id FROM account;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  --
  -- LOOP 
  --  

  OPEN accountids; 
  read_loop: LOOP 
    FETCH accountids INTO accountid;
    IF done THEN 
      LEAVE read_loop;
    END IF;   

    --
    -- INDEX FOR ACTIVITY 
    --  

        SET @update_activity_table_1 = CONCAT("
        IF (
            SELECT COUNT(1) FROM INFORMATION_SCHEMA.STATISTICS
            WHERE `TABLE_SCHEMA` = DATABASE() AND TABLE_NAME='",accountid,"_activity' AND 
            INDEX_NAME='IDX_",accountid,"_ACTIVITY_ACTIVITY_ID'
            ) != 1
        THEN
            ALTER TABLE ",accountid,"_activity 
                ADD KEY `IDX_",accountid,"_ACTIVITY_ACTIVITY_ID` (`activity_id`);
        END IF;
        ");
    PREPARE stmt from @update_activity_table_1; 
    EXECUTE stmt;

    END LOOP; 
  CLOSE accountids;
END$$
DELIMITER ;
CALL update_index_for_table();


Но тогда для некоторыхверсия php / mysql (я думаю), причина ее появления в следующем:

# 1064 - у вас ошибка в синтаксисе SQL;проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса, который нужно использовать рядом с 'IF (SELECT COUNT (1) FROM INFORMATION_SCHEMA.STATISTICS WHERE `TABLE_SCHEM') в строке 1

Я проверял этокод и его работа отлично:

SELECT COUNT(1) FROM INFORMATION_SCHEMA.STATISTICS
WHERE `TABLE_SCHEMA` = DATABASE() AND TABLE_NAME='",accountid,"_activity' AND 
INDEX_NAME='IDX_",accountid,"_ACTIVITY_ACTIVITY_ID'

Вот моя версия php / sql:
phpmyadmin: 4.8.5, версия php: 7.2.7, mysql: 5.6.45

Пожалуйста, помогите, спасибо.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Есть несколько ограничений на то, что вы пытаетесь сделать здесь: 1) вы не можете запустить оператор if из хранимой программы. 2) если вы передаете запрос в динамический sql, и запрос ничего не находит, обработчик продолжения будетбыть вызван и цикл завершится (неожиданно) рано.Подход заключается в том, чтобы разделить функциональность, чтобы сначала проверить существование, добавив «find», чтобы вставить значение в пользовательскую переменную, и в то же время убедиться, что обработчик не был захвачен не найденным путем включения поиска в таблице.который определенно будет содержать что-то (в данном случае information.schema_tables.

Итак, учитывая

DROP PROCEDURE if exists p;
DELIMITER $$
CREATE PROCEDURE p()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE accountid INT;
  --
  -- GET ALL ACCOUNT ID
  --
  DECLARE accountids CURSOR FOR SELECT account_id FROM account;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  --
  -- LOOP 
  --  
  OPEN accountids; 
  read_loop: LOOP 
    FETCH accountids INTO accountid;
    select accountid;
    IF done = true THEN 
        select accountid, 'leaving';
      LEAVE read_loop;
    END IF;   
    --
    -- INDEX FOR ACTIVITY 
    --  
   SET @test := 0; 
    SET @update_activity_table_1 :=
        (concat('SELECT case when index_name is null then 1 else 0 end into @test FROM 
         information_schema.tables it
         left join INFORMATION_SCHEMA.STATISTICS iss ',
         ' on iss.table_schema = it.table_schema and iss.table_name = it.table_name and ',
         'INDEX_NAME=',char(39),'IDX_',accountid,'_ACTIVITY_ACTIVITY_ID',char(39),
        ' WHERE it.TABLE_SCHEMA = ', char(39),'test',char(39), ' AND ',
        'it.TABLE_NAME=',char(39),accountid,'_activity', char(39),
        ';'
        )
        )
    ;
   select @update_activity_table_1;

    PREPARE stmt from @update_activity_table_1;
   EXECUTE stmt;
    deallocate prepare stmt;

    if @test = 1 then
        select 'Did not find index for ' , accountid, '_extract';
    else
        select 'Found index for ' , accountid, '_extract';
    end if;

    END LOOP; 
   CLOSE accountids;
END $$
DELIMITER ;
call p();

, я оставлю вас для построения оператора alter и вставки в оператор if.

0 голосов
/ 26 сентября 2019

Во-первых, я считаю, что accound_id и activity_id являются вашими уникальными ключами, но что не уверен, если вы автоматически увеличиваете его, проверьте, проверяется ли автоматическое увеличение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...