我有一个带有主键的表,auto_increment ID列。当我删除具有最高ID的行(例如ID 100)时,我想仅使用mysql触发器将该ID用于新行。我该怎么做?
当我删除时,例如ID 1且最高ID为100,我不想再使用ID 1。
我使用不同的PHP调用执行delete和insert语句。
答案 0 :(得分:1)
你应该设置AUTO_INCREMENT表选项,例如 -
DELETE FROM table_name WHERE id = 100;
ALTER TABLE table_name AUTO_INCREMENT = 100;
...然后插入新记录。
INSERT INTO table_name (id) VALUES (NULL); --> will add 100
答案 1 :(得分:0)
这是触发器(使用drop / create语句):
DELIMITER $$
DROP TRIGGER IF EXISTS `trigger_name`$$
CREATE
TRIGGER `trigger_name` BEFORE INSERT ON `table_name`
FOR EACH ROW BEGIN
DECLARE inc_val INT;
SET inc_val := (SELECT IFNULL(MAX(ID), 0)+1 FROM table_name)
;
SET NEW.ID = inc_val
;
END;
$$
DELIMITER ;
答案 2 :(得分:0)
我尝试使用auto_increment
更改alter table
值。因为,每次插入时检查都可能导致性能问题。所以我认为在删除完成后放置触发器会更好。
我尝试了这一点并得出结论:Alter table
无法应用于触发器。只做"Alter table"
改变auto_increment
就是这样的解决方案,所以不能采取这种方法。
MySQL提供错误“触发器中不允许显式/隐式提交”。
我建议您创建一个存储过程,然后在从表中删除时调用它。我猜你总是知道你要删除的地方(所以似乎是可行的)。
程序如下:
DELIMITER $$
USE `database_name`$$
DROP PROCEDURE IF EXISTS `new_max`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_max`()
BEGIN
DECLARE i INTEGER;
SET i = (SELECT MAX(id) FROM `table_name`);
SET @ddl = CONCAT('alter table `table_name` auto_increment = ',(i+1));
PREPARE STMT FROM @ddl;
EXECUTE STMT;
END$$
DELIMITER ;
您将其称为call new_max();
使用存储过程,您无需进行大量编程,只需在激活删除命令后在代码中添加简单行,它就可以根据需要使用。希望它有所帮助......
答案 3 :(得分:0)
最后,我找到了解决问题的正确方法。感谢你的所有建议和批评。我现在使用一个程序(感谢@shubhansh的想法)而不是使用触发器。
这是该过程的create语句:
DELIMITER $$
USE `[DATABASE]`$$
DROP PROCEDURE IF EXISTS `[PROCEDURE NAME]`$$
CREATE PROCEDURE `[PROCEDURE NAME]`(deleteID INT(11))
BEGIN
DECLARE i INTEGER;
SET @deleteRow = CONCAT('delete from `[TABLE NAME]` WHERE ID = ', deleteID);
PREPARE a FROM @deleteRow;
EXECUTE a;
SET i = (SELECT IFNULL(MAX(ID), 0) FROM `[TABLE NAME]`);
SET @alterTable = CONCAT('alter table `[TABLE NAME]` auto_increment = ',(i+1));
PREPARE b FROM @alterTable;
EXECUTE b;
END$$
DELIMITER ;
现在我可以在一个PHP语句中删除和更改一个表,并且它是保存的,因为该过程会锁定表。