2012-02-09 73 views
0

我在LAST_INSERT_ID()(或PHP上的mysql_insert_id)和一个带有两个参数(本例)的表中有问题。 ID:autoincremental value TEXT:varchar唯一字段。INSERT INTO错误后的LAST_INSERT_ID()

如果我有这样的:

INSERT INTO field (text) VALUES ('a'); -> Insert OK 
SELECT LAST_INSERT_ID(); -> ok, returns 1; 
INSERT INTO field (text) VALUES ('a'); -> Insert Error (text field is UNIQUE) 
INSERT INTO field (text) VALUES ('b'); -> Insert Ok 
SELECT LAST_INSERT_ID(); -> ok, but returns 3, not 2 

的自动增加字段不相关,和跳2的值。 我试着打开TRANS TRANSACTION和ROLLBACK或COMMIT,但我遇到了同样的问题(或者,我没有正确执行)。

有什么想法?

谢谢。

回答

4

不,增量ID并不总是MAX + 1,如果先按顺序删除先前的记录,也不会重新洗牌。如果您在增量ID序列中存在差距,则无关紧要:如果将增量ID正确地用作唯一标识符,那么这不是问题。如果你依赖于连续的序列,那么你还没有正确设计你的数据库。

+0

感谢您的回答。你能否提供一些想法来正确设计我的数据库?我需要一个连续序列的ID。如果我做了一个INSERT INTO但失败了,我需要下一个INSERT INTO返回ID + 1,而不是ID + 2,3,4 ... – Pipeline 2012-02-09 09:00:26

+0

在绝大多数情况下,连续的ID号不应该是关键的。如果您的情况表明您确实需要保证连续序列的ID号码 - 例如对于在检查书籍时税务人员可能会注意到缺陷的发票编号 - 那么您必须手动执行此操作。保留自动增量列作为主键,但有一个invNo列,通过代码填充(无论数据库触发ON INSERT还是PHP)。你可以总是INSERT而不用invNo,然后UPDATE稍后添加invNo值。 – 2012-02-09 09:05:08

+1

您需要注意尝试同时插入的多个用户。通常情况下,我会有一个单独的“数字”表格,其中包含要使用的下一个数字。当插入新的发票时,锁定该表以防止多个并发访问,读取下一个要使用的数字,然后递增和更新,然后用于我的发票记录...全部在一个事务中。如果插入发票失败,则回滚以还原下一个数字表。如果您发现数字表被锁定,然后重试几次,然后干净地失败。 – 2012-02-09 09:10:55