问题描述
我已经构建了一个存储过程来获取我们数据库中每个 INT 列中的最大值并将其存储到一个表中,并根据该 int 类型的最大允许值计算它的使用百分比。
第一步清理表格并将自动 inc 值设置回比上次使用的值多一个,而不是让 innodb 猜测一些随机的下一个插入起始值。然后,我使用信息模式插入具有该 int 类型允许的模式、表、列、int 类型和 maxValue 的任何列。
很简单,问题出在游标上,在这个数据库的情况下,最后插入的模式记录是针对 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,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(`','`) INTO @value from `','`.`','`;');
-- select x_schemaName as SchemaName;
SET setCurrentValue = CONCAT('update intOverRunLog set currentMaxValue = (select max(`','`) from `','`) where `schemaName` = \'','\' and tableName = \'','\' and 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
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
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)