Хранимая процедура Aurora с сохранением значений

Я создал хранимую процедуру, чтобы получить максимальное значение в каждом столбце INT в нашей базе данных, сохранить его в таблице и вычислить процент использования, исходя из максимального допустимого значения для этого типа int.

Первый шаг очищает таблицу и устанавливает значение auto inc обратно на единицу больше, чем последнее использованное значение, вместо того, чтобы позволять innodb угадывать какое-то случайное следующее начальное значение для вставок. Затем я использую информационную схему для вставки любых столбцов со схемой, таблицей, столбцом, типом int и maxValue, разрешенными для этого типа int.

Достаточно простая проблема заключается в курсоре, в случае этой базы данных последняя вставленная запись схемы предназначена для схемы wordpress. Когда он попадает в цикл курсора, он терпит неудачу, потому что по какой-то причине он использует wordpress для значения в первой итерации цикла.

      DROP PROCEDURE if exists log_int_over_run;
DELIMITER ;;
CREATE PROCEDURE `log_int_over_run`()
MODIFIES SQL DATA
not deterministic
BEGIN
        DECLARE x_id INT;
        DECLARE x_currentMaxValue BIGINT(20);
        DECLARE x_schemaName VARCHAR(50) DEFAULT 0;
        DECLARE x_tableName VARCHAR(50) DEFAULT 0;
        DECLARE x_columnName VARCHAR(50) DEFAULT 0;
        DECLARE setCurrentValue VARCHAR(400);
        DECLARE setLargerValue VARCHAR(400);
        DECLARE last_row INT;
        DECLARE current_max INT;
        DECLARE columns CURSOR FOR select id,schemaName,tableName,columnName,currentMaxValue from datateam.intOverRunLog where tableName !='intOverRunLog' and `ignore` != 1 order by id;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET last_row = 1;
        SET last_row=0;
                -- Remove any weird auto_inc gaps at the end of that last insert
    SET @m = (SELECT IFNULL(MAX(id),0) + 1 FROM datateam.intOverRunLog); 
    SET @s = CONCAT('ALTER TABLE datateam.intOverRunLog AUTO_INCREMENT=', @m);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

     -- Load up any new tables
    insert ignore INTO datateam.intOverRunLog (schemaName,tableName,columnName,dataType,`maxValue`)
    select C.TABLE_SCHEMA,C.TABLE_NAME,C.COLUMN_NAME,C.COLUMN_TYPE,
    @max_value := CASE
        WHEN COLUMN_TYPE like  'int(%) unsigned' THEN 4294967295
        WHEN COLUMN_TYPE like 'int(%)' THEN 2147483647
        WHEN COLUMN_TYPE like 'bigint(%) unsigned' THEN 18446744073709551615
        WHEN COLUMN_TYPE like 'bigint(%)' THEN 9223372036854775807
        WHEN COLUMN_TYPE like 'mediumint(%) unsigned' THEN 16777215
        WHEN COLUMN_TYPE like 'mediumint(%)' THEN 8388607
        WHEN COLUMN_TYPE like 'smallint(%) unsigned' THEN 65535
        WHEN COLUMN_TYPE like 'smallint(%)' THEN 32767
        WHEN COLUMN_TYPE like 'tinyint(%) unsigned' THEN 255
        WHEN COLUMN_TYPE like 'tinyint(%)' THEN 127
        ELSE "UNKNOWN"
    END as max_value
    FROM information_schema.columns C
        JOIN  information_schema.tables T on C.TABLE_SCHEMA = T.TABLE_SCHEMA and C.TABLE_NAME = T.TABLE_NAME
    where C.TABLE_SCHEMA NOT IN ('information_schema','performance_schema','mysql','sys') 
    and C.TABLE_NAME NOT IN ('intOverRunLog')
    AND COLUMN_TYPE like 'int%';
        
        -- TODO Deactivate any tables/columns that may have changed
        
        
        -- Get a list of schema/table/columns and iterate through it 
        
        OPEN columns;
        column_cursor : LOOP
            -- SET @value = NULL;
            
            FETCH columns INTO x_id,x_schemaName,x_tableName,x_columnName,x_currentMaxValue;
            IF last_row=1 THEN
                LEAVE column_cursor;
            END IF;
            select x_schemaName;
            -- SET setCurrentValue = CONCAT('select max(`',x_columnName,'`) INTO @value from `',x_schemaName,'`.`',x_tableName,'`;');
            -- select x_schemaName as SchemaName;
            SET setCurrentValue = CONCAT('update intOverRunLog set currentMaxValue = (select max(`',x_columnName,'`) from `',x_schemaName,'`.`',x_tableName,'`) where `schemaName` = \'',x_schemaName,'\' and tableName = \'',x_tableName,'\' and columnName = \'',x_columnName,'\';');
            SET @sql=setCurrentValue;
            select @sql;
            PREPARE s1 FROM @sql;
            EXECUTE s1;
            DEALLOCATE PREPARE s1;
            IF @value IS NOT NULL THEN
                select x_id,current_max as tableValue,x_currentMaxValue as currentMaxValue,current_max as `second`;
            END IF;
        END LOOP column_cursor;
        
        CLOSE columns;
    
END;;
DELIMITER ;

Когда я запускаю его, я получаю:

      ERROR 1146 (42S02): Table 'wordpress.apiLog' doesn't exist

И вывод переменной @sql:

      update intOverRunLog set currentMaxValue = (select max(`id`) from `wordpress`.`apiLog`) where `schemaName` = 'wordpress' and tableName = 'apiLog' and columnName = 'incoming_link_count';

Первая схема в таблице intOverRunLog - «архив». Итак ... зачем было устанавливать переменную x_schemaName на wordpress? Похоже, это связано с insert ignore часть, если я вынимаю ее, она работает нормально.

Также вот определение таблицы, в которую я вставляю это:

      CREATE TABLE `intOverRunLog` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `schemaName` varchar(50) NOT NULL,
  `tableName` varchar(50) NOT NULL,
  `columnName` varchar(50) NOT NULL,
  `dataType` varchar(50) NOT NULL,
  `maxValue` bigint(20) NOT NULL,
  `currentMaxValue` bigint(20) NOT NULL,
  `pct` float(10,2) GENERATED ALWAYS AS (((`currentMaxValue` / `maxValue`) * 100)) VIRTUAL,
  `ignore` tinyint(1) NOT NULL DEFAULT '0',
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modifed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_key` (`schemaName`,`tableName`,`columnName`,`dataType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

0 ответов

Другие вопросы по тегам