我有一张这种结构的桌子:
当我在表格中添加新行时,| ID |名称|
id 正在递增。 例如,我有3行:
1|John
2|Bob
3|Alice
如果我删除 ID为 2 的行,则会有:
1|John
3|Alice
如果我不知道ID为空,如何插入 ID = 2 的新行?
(或者 - 如何插入具有未使用的id(自动增量)值的行?)
感谢。
答案 0 :(得分:1)
您可以使用此查询获取最少未使用的ID。
SELECT (Min(ID) + 1) AS NewIDToInsert
FROM TableName T2A
WHERE NOT EXISTS (SELECT ID FROM TableName T2B WHERE T2A.ID + 1 = T2B.ID)
答案 1 :(得分:0)
在INSERT上,如果不是ROWID或INTEGER PRIMARY KEY列 明确给出一个值,然后它会自动填充一个 未使用的整数,通常是当前最大的ROWID之一 正在使用。无论AUTOINCREMENT是否正确,都是如此 使用了关键字。
换句话说,您应该能够在执行插入时明确指定id
,并且不会自动增量。
答案 2 :(得分:0)
我使用this answer编写了一个适用于mysql-5.7的存储过程,该存储过程用最大ID填充空ID。
SELECT
*
FROM
tableName
;
CALL sp_fill_empty_ids('tableName');
DELIMITER $$
CREATE PROCEDURE sp_fill_empty_ids(IN tableName VARCHAR(64))
BEGIN
SET @minEmptyId := 0;
SET @maxId := 0;
CALL statement(CONCAT('
SET @maxId = (
SELECT MAX(Id)
FROM ', tableName,'
);
'));
CALL statement(CONCAT('
SET @minEmptyId = (
SELECT (Min(ID) + 1) AS NewIDToInsert
FROM ', tableName,' T2A
WHERE NOT EXISTS (SELECT ID FROM ', tableName,' T2B WHERE T2A.ID + 1 = T2B.ID)
);
'));
WHILE ( @minEmptyId <> (@maxId + 1) ) DO
CALL statement(CONCAT('
SET @minEmptyId = (
SELECT (Min(ID) + 1) AS NewIDToInsert
FROM ', tableName,' T2A
WHERE NOT EXISTS (SELECT ID FROM ', tableName,' T2B WHERE T2A.ID + 1 = T2B.ID)
);
'));
CALL statement(CONCAT('
-- SELECT * FROM
UPDATE
', tableName, '
SET Id = @minEmptyId
WHERE Id = @maxId
;
'));
SET @maxId = @minEmptyId
;
END WHILE;
CALL statement(CONCAT('
ALTER TABLE ', tableName,'
AUTO_INCREMENT = ', @minEmptyId))
;
END$$
DELIMITER ;
statement
的实现方式:
DELIMITER $$
CREATE PROCEDURE statement(IN dynamic_statement TEXT)
BEGIN
SET @dynamic_statement := dynamic_statement;
PREPARE prepared_statement FROM @dynamic_statement;
EXECUTE prepared_statement;
DEALLOCATE PREPARE prepared_statement;
END$$
DELIMITER ;