首先,我是业余和非英语母语人士,所以如果你对我有点耐心,我会很感激;)
试着在这里做两件事,我不确定我是否应该对它做两个问题,但由于这一切都与我的情况有关,我想在一个问题中说出这一切。
我正在制作一种会计软件,理论上是为了我的个人用途。我正在为几乎所有的对象使用DB生成的auto_increment ID,但是对于某些特定情况,我需要一个“并行”更开放的ID,它不是主键但可以被用户操纵(是的,我读过关于“你不需要一个连续的主键”的很多问题,我理解并同意,但是请注意,这个专栏不会是主键,让我们称之为符合这些条件的“人 - 非计算机专家友好ID”:
DELETE
和其他任何操作填写缺失的ID,因此如果用户“说是”,则应自动找到并使用最小缺失ID。 我在c#中“手动”执行此操作没有任何问题,但有没有办法直接在MySQL中实现这样的功能?我在MySQL文档中读到AUTO_INCREMENT
确实满足了我的前两个条件,但即使它默认填充缺少的已删除数字,我也不确定,我不希望它通过默认情况下,我需要首先询问软件,或者至少根据用户预先建立的配置来执行此操作。
因此我认为我应该在c#手工完成(至少在最后一部分,但我怀疑我将被迫完全这样做),这带来了关于LAST_INSERT_ID
的问题。
所以,MYSQL文档说:
如果前一个语句返回错误,则LAST_INSERT_ID()的值未定义。对于事务表,如果由于错误而回滚语句,则LAST_INSERT_ID()的值未定义。对于手动ROLLBACK,LAST_INSERT_ID()的值不会恢复到事务之前的值;它仍然像ROLLBACK那样。
据我所知,如果之前的LAST_INSERT_ID()
语句因任何原因失败,INSERT
基本无用。
如果是这种情况,那么无法检索最后插入的ID,以确保在出现故障时的已知行为?像INSERT
失败时返回0或SQL异常的东西?如果没有别的办法是什么标准的做法(我认为MAX(Id)
不会这样做),如果存在类似标准方式的东西......或者我应该停止尝试在一个首先进行更新,检查一切是否正常,然后进行SELECT LAST_INSERT_ID
?
总结一下:
LAST_INSERT_ID
有什么用?我应该放弃而不是直接使用它吗?答案 0 :(得分:1)
情况1,知道要插入AUTO_INCREMENT
表示AI不是所描述的PK。
-- drop table a12b;
create table a12b
( id varchar(100) primary key,
ai_id int not null AUTO_INCREMENT,
thing varchar(100) not null,
key(ai_id)
);
insert a12b (id,thing) values ('a','fish'); -- ai_id=1
insert a12b (id,thing) values ('b','dog'); -- 2
insert a12b (id,thing) values ('b2','cat'); -- 3
delete from a12b where id='b';
insert a12b(id,ai_id,thing) values ('b',2,'dog with spots'); -- 2 ******** right here
insert a12b (id,thing) values ('z','goat'); -- 4
select * from a12b;
+----+-------+----------------+
| id | ai_id | thing |
+----+-------+----------------+
| a | 1 | fish |
| b | 2 | dog with spots |
| b2 | 3 | cat |
| z | 4 | goat |
+----+-------+----------------+
4 rows in set (0.00 sec)
情况2,有一个系统可以在某个时刻删除行。并希望稍后填写明确删除的差距:请参阅我的回答Here
情况3(INNODB散布着一大堆空白):
这不是问题的一部分。也许使用一个使用帮助表的左连接(至少对于不是varchars的int。但是我们再次谈论的是int)。如果您需要在不知情的情况下发现间隙,请使用辅助表(加载数字)进行左连接。我知道这听起来很蹩脚,但帮助表很精简,意味着完成工作。以下是帮助表:https://stackoverflow.com/a/33666394
使用上面的4行表格,继续:
insert a12b (id,thing) values ('z','goat'); -- oops, problem, failed, but AI is incremented behind the scene
insert a12b (id,thing) values ('z2','goat'); -- 6 (you now have a gap)
data:
+----+-------+----------------+
| id | ai_id | thing |
+----+-------+----------------+
| a | 1 | fish |
| b | 2 | dog with spots |
| b2 | 3 | cat |
| z | 4 | goat |
| z2 | 6 | goat |
+----+-------+----------------+