1

对于特定表,我将 ID 字段设置为自动编号(增量)。如果我快速连续向该表添加 5 行,是否保证每行的 ID 都比上一个大?例如,如果一些较早的值已被删除,自动编号是否会从 1 重新开始?

4

9 回答 9

3

我唯一遇到过 Access 自动编号问题的情况是,我错误地使用附加查询将自动编号键字段的值设置为低于当前最大值的数字。记录删除在编号中造成了空白。Access 允许您将一个值强制输入自动编号字段,有时(并非总是如此,我不知道为什么)自动编号​​会重置为较小的数字。最终,随着记录的添加,我遇到了“重复键”错误。除此之外,我多年来从未遇到过麻烦。

这个问题有几个关于增量值的答案。据我所知,Access自动编号字段只能设置为'Increment'(1)或'Random',并且没有设置除1以外的数字增量。如果我对此有误,请指教我。

于 2009-04-20T02:31:01.650 回答
3

可悲的是,即使是微软的应用程序也不是万无一失的。但这就是它的工作方式,我还没有看到它失败。也没有听说过它没有故意或偶然的颠覆。

不过,不要指望它对每个整数值都有一行。除了删除的行之外,它还会用完失败的追加操作的数字。

于 2009-04-20T02:40:51.093 回答
2

语句“如果删除了一些记录并且压缩了数据库,则下一个身份将重置为使用的最低数字 + 1”是不正确的。这发生在 Access 97 中使用的 Jet 3.5 中,但在 Access 2000 中使用的 Jet 4.0 中没有。

于 2009-04-21T01:53:03.853 回答
2

David W. Fenton 写道:“Jet Autonumber 字段不是身份字段。它只是一个具有特殊默认值的长整数字段。该默认值可以是 INCREMENT 或 RANDOM,但由于它只是一个默认值,因此您可以只要不违反索引,就将任何长整数值附加到该字段。”

这有点困惑。ACE/Jet SQL 语法有一个IDENTITY关键字 ( COUNTER, AUTOINCREMENT) 但没有 AUTONUMBER 关键字。显然 ACE/JetIDENTITYIDENTITY!

但我想在这里解决的问题(评论太长)是关于它是“只有一个具有特殊默认值的长整数字段”的错误陈述。

考虑这个 ACE/Jet SQL DDL(ANSI-92 查询模式语法):

CREATE TABLE Test2_IDENTITY
(
   ID_identity_1 IDENTITY NOT NULL, 
   ID_identity_2 IDENTITY NOT NULL, 
   data_column INTEGER
);

执行时,它会失败并显示消息“结果表不允许有多个自动编号字段”。很明显,这里发生的不仅仅是“特殊默认值”。

关键字是使用IDENTITY递增算法创建一个自动编号(因为需要更好的术语)来生成值。IDENTITY不能用于使用随机算法或自动编号的 GUID(复制 ID)风格创建自动编号。对于这些其他情况,您确实需要使用“特殊默认值”,例如

CREATE TABLE TestAutonumbers 
(
   ID_identity IDENTITY NOT NULL, 
   ID_random INTEGER DEFAULT GenUniqueID() NOT NULL, 
   ID_guid UNIQUEIDENTIFIER DEFAULT GenGUID() NOT NULL, 
   data_col INTEGER
);

如果您使用诸如 ADOX 之类的技术来检查该表的属性(信息模式),您会发现只有使用 IDENTITY 关键字创建的列的 Autoincrement 属性设置为 true,并且该列的 COLUMN_HASDFAULT 为 false,COLUMN_DEFAULT 为 null。因此,如果 IDENTITY 列确实具有“特殊默认值”,那么引擎不会告诉您。

不同IDENTITY的是,对于这些其他风格的自动编号,每个表都没有明确的限制,例如这很好用:

CREATE TABLE Test2_Autonumbers
(
   ID_random_1 INTEGER DEFAULT GenUniqueID() NOT NULL, 
   ID_random_2 INTEGER DEFAULT GenUniqueID() NOT NULL, 
   ID_guid_1 UNIQUEIDENTIFIER DEFAULT GenGUID() NOT NULL, 
   ID_guid_2 UNIQUEIDENTIFIER DEFAULT GenGUID() NOT NULL, 
   data_col INTEGER
);

我不知道是否存在与使用和不使用关键字(或其同义词)创建自动增量列等效的“特殊GenUniqueID()默认值” GenGUID()。如果有人知道其中一种方法,请告诉我。DEFAULTIDENTITY

顺便说一句,上述错误消息表明我对“自动编号”作为访问术语是错误的。似乎在 ACE/Jet 引擎级别“自动编号”是(即自动增量风格自动编号)的非关键字同义词,IDENTITY但不是其他自动编号风格的同义词。

于 2009-04-22T10:13:15.857 回答
1

首先,您的IDENTITY(Autonumber in Access) 列必须是INTEGER(Long Integer in Access) 而不是UNIQUEIDENTIFIER(Replication ID in Access),必须使用增量算法而不是随机算法来生成新值并分别假设您的种子和增量值都是默认值 1,那么如果您删除表中的所有行并压缩数据库,则该IDENITTY列应重新设置为 1。如果不是,则您可能需要安装 Jet 服务包(http:// support.microsoft.com/kb/287756)。

请注意,当 (Long Integer in Access) 的最大正值INTEGER被下一个自动生成的值超过时,它将“换行”到负INTEGER范围内,并将继续在正负范围之间循环,生成重复值,其中必要的(除非该列另外被唯一约束覆盖)。实际上,如果增量值足够大,您可以保证这些值将在大于和小于先前自动生成的值之间交替,例如(ACE/Jet ANSI-92 查询模式语法):

CREATE TABLE Test 
(
   ID INTEGER IDENTITY (0, 2147483647), 
   data_col INTEGER NOT NULL UNIQUE
)
;
INSERT INTO Test (data_col) VALUES (1)
;
INSERT INTO Test (data_col) VALUES (2)
;
INSERT INTO Test (data_col) VALUES (3)
;
INSERT INTO Test (data_col) VALUES (4)
;
INSERT INTO Test (data_col) VALUES (5)
;
INSERT INTO Test (data_col) VALUES (6)
;
INSERT INTO Test (data_col) VALUES (7)
;
INSERT INTO Test (data_col) VALUES (8)
;

自动生成的值为 0、2147483647、-2、2147483645、-4、2147483643、-6、2147483641 等。

于 2009-04-20T08:14:30.327 回答
1

我有一个以前在复制数据库中使用的表。有些自动编号是负数,有些非常大。这对于复制表来说是正常的,因此您不能确定自动编号是否会大于先前的数字,它可能是负数。

于 2009-04-20T12:14:15.303 回答
1

Jet Autonumber 字段不是身份字段。它只是一个具有特殊默认值的长整数字段。该默认值可以是 INCREMENT 或 RANDOM,但由于它只是一个默认值,您可以将任何长整数值附加到该字段,只要它不违反索引。

递增的自动编号永远不会恢复为 1,除非您已删除所有记录并进行了压缩,或者在种子值损坏的情况下。后者在 Jet 4 的早期版本(Service Pack 6 之前)中经常发生,其中种子值会被重置,这会导致各种问题,包括损坏的 PK 索引。幸运的是,这个问题最终得到了解决,而且因为 Jet 是一个 Windows 组件,所以几乎没有任何计算机会比 Jet 4 service pack 8 少。

正如 onedaywhen 所说,如果递增的自动编号超过长整数的最大正值,您可以获得负值,但这向我表明您的表中可能有足够的记录,您需要不同的数据库引擎,或者您不正确将您的表视为临时表(即追加和删除大量记录)。

正如其他人所说,唯一性不是由自动编号数据类型控制,而是由索引控制。如果您创建了非唯一索引,则可以附加重复值。我无法想象你为什么想要一个具有重复值的自动编号字段,但关键是如果你不添加唯一索引,你可以做到这一点。由于大部分 Autonumber 字段都用作代理主键,因此它们将具有唯一的 PK 索引,并且数据表将按 PK 顺序(聚集)写入。关于唯一性,如果您使用自动编号作为代理 PK,并且表中有任何应该唯一的自然键(并且可以是唯一的,即不允许 Null),则您还应该在自然键字段(单个字段或复合索引)。

于 2009-04-20T20:36:06.703 回答
1

我的答案是 3 串 VBA 代码!

Set db = CurrentDb
Set tbl = db.TableDefs("your_tbl")
Set current_index = tbl.Indexes.Item("PrimaryKey").DistinctCount
于 2011-12-19T13:03:42.390 回答
0

如果删除了一些记录并且压缩了数据库,则下一个标识将重置为使用的最低数字 + 1 - 如果表被清空,则在压缩后下一个标识将设置回 1。

于 2009-04-20T15:24:34.473 回答