问题
I have a table with a primary key, auto_increment ID column. When I delete the row with the highest ID, for instance ID 100, I want to use that ID 100 for a new row only using a mysql trigger. How do I do that?
When I delete, for instance ID 1 AND the highest ID is 100, I don't want to use ID 1 again.
I do the delete and insert statement with different PHP calls.
回答1:
You should set AUTO_INCREMENT table option, e.g. -
DELETE FROM table_name WHERE id = 100;
ALTER TABLE table_name AUTO_INCREMENT = 100;
...then insert new records.
INSERT INTO table_name (id) VALUES (NULL); --> will add 100
回答2:
Here's the trigger (with drop / create statement):
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 ;
回答3:
I tried to change auto_increment
value using alter table
. Since, checking each time at insert might lead to performance issues. So I thought its better to put trigger when deletion is done.
I tried this and came to conclusion that Alter table
can't be applied in triggers. And Doing only "Alter table"
to change auto_increment
is solution this way, So this approach can't be taken.
MySQL gives error "Explicit/Implicit Commits are not allowed in Trigger".
I suggest you to create a stored procedure and then call it when ever you are deleting from table. I guess you always know where you are deleting(so seems to be feasible).
The procedure is as follows:
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 ;
And you will be calling it as call new_max();
With stored procedure, you need not do much of programming, just add simple line in your code after delete command is fired and it will work as you want. Hope it helps....
回答4:
Finally I found the right solution for my problem. Thanks to all your suggestions en criticism. Instead of using a trigger, I now use a procedure (thanks for the idea @shubhansh).
This is the create statement for the procedure:
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 ;
Now I can delete and alter one table in one PHP statement and it is save because the procedure locks the table.
来源:https://stackoverflow.com/questions/11739793/use-the-next-possible-primary-key-on-auto-increment-column-after-deleting-one-or