我有一个带有主键 auto_increment ID 列的表。当我删除具有最高 ID 的行时,例如 ID 100,我只想使用 mysql 触发器将该 ID 100 用于新行。我怎么做?
当我删除时,例如 ID 1 并且最高 ID 为 100,我不想再次使用 ID 1。
我使用不同的 PHP 调用执行删除和插入语句。
您应该设置 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
这是触发器(使用 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 ;
我尝试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();
使用存储过程,您无需进行太多编程,只需在触发删除命令后在代码中添加简单的行,它就会按您的意愿工作。希望能帮助到你....
最后,我找到了解决问题的正确方法。感谢您的所有建议和批评。我现在没有使用触发器,而是使用了一个过程(感谢@shubhansh 的想法)。
这是该过程的创建语句:
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 语句中删除和更改一个表,它被保存,因为过程锁定了表。