views:

2671

answers:

9

For a particular table, I have my ID field set to AutoNumber (Increment). If I add 5 rows to this table in quick succession, is each guaranteed to have a larger ID than the last? For instance, does autonumbering ever restart from 1 if some earlier values have been deleted?

+2  A: 

The only time I have ever had trouble with Access autonumbers is when, in error, I set the value of an autonumber key field to a number lower than the current maximum using an append query. Gaps had been created in the numbering by record deletions. Access allows you to force a value into an autonumber field, and sometimes (not always, and I don't know why) the autonumbering gets reset to the lower number. Eventually, as records were added, I ran into 'duplicate key' errors. Other than this, I've never had trouble in many years.

There are a couple of answers to this question which talk about an increment value. As far as I know, an Access autonumber field can only be set to 'Increment' (by 1) or 'Random', and there is no way of setting a numeric increment other than 1. If I am wrong about this, please enlighten me.

dsteele
I'm not aware of any option to specify the increment via the Access UI. However, SQL DDL gives you options. onedaywhen demonstrated a CREATE TABLE. You could also do an ALTER TABLE. Either way allows you to specify both the seed and increment values.
HansUp
I stand corrected. The code that onedaywhen provided doesn't work in Access, but I did find after experimenting that "CREATE TABLE testit (id AUTOINCREMENT(0,5), teststr CHAR)" does work. The things you learn!
dsteele
+3  A: 

Sadly, even Microsoft's applications are not infallible. But that's the way it's intended to work, and I've not seen it fail; nor heard of it fail short of intential or accidental subversion.

Just don't expect it to have a row for every integer value, though. In addition to deleted rows, it will use up numbers for append operations that fail.

le dorfier
+1  A: 

First, your IDENTITY (Autonumber in Access) column must be INTEGER (Long Integer in Access) as opposed to UNIQUEIDENTIFIER (Replication ID in Access), must use the increment algorithm as opposed to the random algorithm for generating new values and assuming your seed and increment values respectively are both the default value 1, then if you delete all the rows in the table and compact the database then the IDENITTY column should be reseeded at 1. If it doesn't then you may need to install a Jet service pack (http://support.microsoft.com/kb/287756).

Note that when the maximum positive value for INTEGER (Long Integer in Access) would be exceeded by the next auto-generated value then it will 'wrap' into the negative INTEGER range and will continue to cycle through the positive and negative ranges, generating duplicate values where necessary (unless the column is additionally covered by a unique constraint). Indeed, if the increment value is large enough you can guarantee that the values will alternate between being greater than and less than the previous auto-generated value e.g. (ACE/Jet ANSI-92 Query Mode syntax):

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)
;

The auto-generated values are 0, 2147483647, -2, 2147483645, -4, 2147483643, -6, 2147483641, etc.

onedaywhen
...and here's a picture of how it wraps: http://xkcd.com/571/
onedaywhen
+1  A: 

I have a table that was formerly used in a replicated database. Some of the autonumbers are negative, and some are very large. This is normal for a replicated table, so you cannot be certain that an autonumber will be larger than the previous number, it could be negative.

Remou
This is because when a Jet database is replicated, Autonumbers are converted from INCREMENT to RANDOM. This is required, since otherwise, you'd end up with immediate collisions between different replicas.
David-W-Fenton
That is, the next value is going to be larger if your Autonumber is using INCREMENT for the next value and you have not reached the maximum positive value.
David-W-Fenton
A: 

If some records are deleted AND the database is compacted the next identity is reset to the lowest used number + 1 - if the table is emptied the next identity is set back to 1 after the compact.

DJ
A: 

It sounds like you maybe want a method to determine the order in which records are added. If that is so, consider whether a Date/Time field ("when_added") with a default value "=Now()" would satisfy your need. The time resolution may not be fine enough for you, but don't dismiss it without looking first.

I'm generally uncomfortable about trying to assign additional meaning to an autonumber.

HansUp
+1  A: 

The Jet Autonumber field is not an identity field. It is only a long integer field with a special default value. That default value can be INCREMENT or RANDOM, but as it is only a default value, you can append any long integer value to the field as long as it doesn't violate the index.

An incrementing Autonumber will never revert to 1 except if you've deleted all records and compacted, or in the event of a corrupt seed value. The latter happened frequently in the early versions of Jet 4 (before service pack 6), where the seed value would get reset, and this would lead to all sorts of problems, including corrupted PK indexes. Fortunately, that eventually got fixed, and because Jet is a Windows component, hardly any computer out there is going to have anything less than Jet 4 service pack 8.

As onedaywhen said, you can get negative values if the incrementing Autonumber exceeds the maximum positive value for long integer, but this would indicate to me that you probably have enough records in your table that you need a different database engine, or you're improperly treating your table as a temp table (i.e., appending and deleting large numbers of records).

As others have also said, uniqueness is not controlled by the Autonumber data type, but by the index. If you created a non-unique index, you could append duplicate values. I can't imagine why you'd want an Autonumber field with duplicate values, but the point is that you can do it if you don't add a unique index. Since most Autonumber fields are used as surrogate primary key, they will have the unique PK index, and the data table will be written in PK order (clustered). In regard to uniqueness, if you are using an Autonumber as a surrogate PK and you have any natural keys in the table that should be unique (and can be unique, i.e., no Nulls allowed), you should also have a unique index on the natural key field(s) (a single field or a compound index).

David-W-Fenton
Why would you want to cluster on an Autonumber? Can't be to optimize querying so I guess you must using RANDOM to favour concurrency i.e. you are a known DAO user and DAO only supports page level locking.
onedaywhen
"The Jet Autonumber field is not an identity field" I thought semantics were important to you?! 'Autonumber' is an Access term. The ACE/Jet keywords are COUNTER, AUTOINCREMENT and IDENTITY. So, a ACE/Jet IDENTITY is an Access Autonumber with increment algorithm.
onedaywhen
"An incrementing Autonumber will never revert to 1 except if you've deleted all records and compacted, or in the event of a corrupt seed value" -- there is a further case: it can be explicitly reseeded using SQL DDL (or a component such as ADOX which does the same) e.g. ALTER TABLE MyTable ALTER ID INTEGER(500, 5) NOT NULL; (this is an example of why all users having admin privileges can be a problem!!)
onedaywhen
Jet data tables are clustered on the PK, so if you have an Autonumber as you PK, it will be clustered on that field. Dunno what you mean about RANDOM and concurrency. I'd only recommend random Autonumbers outside a replica if edits were heavily concentrated on recently added records, which would mean that a random Autonumber PK would spread the newest records out over many data pages, which could improve concurrency. But I made no such recommendation.
David-W-Fenton
Perhaps I don't understand the definition of "identity field," but my understanding from the SQL specs is that an identity field cannot be written to, either with a SQL UPDATE or a SQL INSERT. While there may be any number of implementations of something called "identity fields" in various db engines that don't meet that requirement, I think it's important to make the distinction with the Jet Autonumber.
David-W-Fenton
When I made my statement about Autonumber never reverting to 1, I was assuming that the fact that we were talking about not explicitly telling Jet to revert the seed value to 1. In other words, in normal data editing by a client application, the Autonumber will not revert to 1 except under the circumstances I outlined. Running DDL statements is not "normal data editing by a client application," which I assumed (perhaps wrongly) was the context of the discussion.
David-W-Fenton
"Jet Autonumber" is an oxymoron. Autonumber is a term used in the Access interface. IDENTITY is an ACE/Jet keyword (synonyms are COUNTER and AUTOINCREMENT). Jet has no AUTONUMBER keyword. If you use the ACE/Jet keyword IDENTITY for a column in a CREATE TABLE or ALTER TABLE statement and then view the table in Access then it would appear as 'Autonumber'. So I would expect someone who values the distinction between Access and ACE/Jet to refrain from referring to an ACE/Jet IDENTITY an Autonumber.
onedaywhen
"my understanding from the SQL specs is that an identity field cannot be written to" -- do you mean the ACE/JET SQL specs? I didn't know there was any! Regardless, your specs are wrong :( You can indeed INSERT an explicit value into an ACE/Jet IDENTITY column. I trust you don't use 'SQL' to mean 'SQL Server', which would be the wrong product entirely.
onedaywhen
You seem to recommend an INCREMENT autonumber be used as a PK but in my experience one should reserve the clustered index for a purpose e.g. to favour concurrency as you describe (but that requires RANDOM) or to favour queries with BETWEEN, GROUP BY, etc. I can't see how a monotonic integer sequence would benefit from being the clustered index. You got the (misplaced) benefit of the doubt about RANDOM. So please explain your thinking on INCREMENT autonumber PKs.
onedaywhen
So for you deleting all rows from a table then compacting the file is a "normal data editing by a client application"?! So like a scratch table but you have to kick all users out so the file can have some routine maintenance just so you can reseed the autonumber? Doesn't sound very 'normal' to me but each to their own. I think an ALTER TABLE SQL DDL statement would be less intrusive!
onedaywhen
@onedaywhen: When you say "Autonumber is a term used in the Access interface" you're confusing Jet with Jet SQL. The Jet Database Engine Programmer's Guide uses the term "Autonumber" and it's a book about Jet, not about Access. Every database has terminology that is not included in its SQL dialect.
David-W-Fenton
When I say "SQL Specs" I mean the theoretical definitions used by the standards-setting bodies, e.g., ANSI and so forth. No Jet documentation that I know of calls Jet Autonumber fields "identity fields," and that's because they aren't. An Autonumer is just a Jet long integer field with a special kind of default value. It is writable via an append but not once populated.
David-W-Fenton
@onedaywhen write: "I can't see how a monotonic integer sequence would benefit from being the clustered index." I don't know if it does. But Jet by definition clusters on the PK and on no other index. That's the way Jet works, period, end of statement. It's different from, say, SQL Server, where you can cluster on the index of your choice.
David-W-Fenton
Deleting all the records in a table is something a user might be able to do using just the UI (assuming they have the appropriate permissions). Writing DDL is not something users are going to do, unless you have a pretty weird definition of "users." Neither is something a properly designed application is going to allow a user to do. I think you don't really use Access and thus your perspective about "users" is not at all realistic.
David-W-Fenton
In Jet you can too cluster on the columns of your choice by using the PRIMARY KEY wisely. My whole point here is that if you are using the PK/clustered index for an incrementing integer then you are not optimizing your indexes, rather you are squandering the table's one and only physical index. As you say yourself, "I never care what the Autonumber values are" so why then choose to cluster on them?!
onedaywhen
@Daivd: "No Jet documentation that I know of calls Jet Autonumber fields "identity fields,". Erm, have you looked? e.g. "Description of the new features that are included in Microsoft Jet 4.0" (http://support.microsoft.com/kb/275561): The following shows an example of how to define an auto-incrementing field: "CREATE TABLE TableName (FieldName1 IDENTITY (10, 5), ...The keyword Counter can be used instead of the keyword Identity."
onedaywhen
"ACC2000: Jet IDENTITY Datatype Seed and Increment Reset to 1" (http://support.microsoft.com/kb/202117).
onedaywhen
"HOW TO: Retrieve the Identity Value While Inserting Records into Access Database By Using Visual Basic .NET" (http://support.microsoft.com/kb/815629). And just look: Microsoft calls it an Access Database ;-)
onedaywhen
"When I say "SQL Specs" I mean the theoretical definitions used by the standards-setting bodies" -- are you saying there is an actual ANSI soec that defines IDENTITY or merely a theoretical one?
onedaywhen
"When I say "SQL Specs" I mean the theoretical definitions used by the standards-setting bodies" -- are you saying there is an actual ANSI soec that defines IDENTITY or merely a theoretical one?
onedaywhen
"An Autonumer is just a Jet long integer field with a special kind of default value. It is writable via an append but not once populated." -- so it has a special default, special protection against updates, a special designation in the schema information, and unlike other data types is limited to one per table, but still is just a plain ordinary INTEGER column. Oh yeah, right.
onedaywhen
@onedaywhen wrote "As you say yourself, 'I never care what the Autonumber values are' so why then choose to cluster on them?!" There is no choice to cluster. You choose your PK, either a natural key or a surrogate key (which is where the Autonumber comes in), and Jet clusters on the PK. Multi-column natural keys are not terribly easy to use (when they can be used at all, i.e., there are no Null columns), and that's why surrogate keys are so useful. Jet simply offers no choice in clustering.
David-W-Fenton
@onedaywhen writes: "CREATE TABLE TableName (FieldName1 IDENTITY (10, 5)..." Have you tried running that SQL in Access? It's not Jet SQL. It's ANSI 92 compatible SQL which in Access requires a special setting (to explicitly tell Access not to use it's native SQL dialect), or you have to use ADO to execute it. ADO is a translation layer and not native SQL. What you're seeing in that article is the awful aftermath of MS's stupid ADO-everywhere campaign, which they have now abandoned.
David-W-Fenton
@onedaywhen: "ACC2000: Jet IDENTITY Datatype Seed and Increment Reset to 1 (http://support.microsoft.com/kb/202117)." The DoCmd.RunSQL code there won't run unless you've got Access set to ANSI 92 mode. Terrible documentation on MS's part as it doesn't say that anywhere in the article. Again, you're citing articles that explicitly use something other than NATIVE JET interfaces to say that Jet documentation uses "IDENTITY" as the term to refer to Autonumber fields -- and you are wrong.
David-W-Fenton
@onedaywhen: "HOW TO: Retrieve the Identity Value While Inserting Records into Access Database By Using Visual Basic .NET" (http://support.microsoft.com/kb/815629)." The article uses non-native data interface library, i.e., ADO/OLEDB. @onedaywhen: "And just look: Microsoft calls it an Access Database" I have frequently pointed out that MS documentation obfuscates the difference between Access and Jet.
David-W-Fenton
@onedayone: "are you saying there is an actual ANSI soec that defines IDENTITY or merely a theoretical one?" Well, I *thought* there was one, but the official SQL 92 spec does not use the term "IDENTITY", so it would appear that the meaning of IDENTITY is implementation-specific. Oracle doesn't allow appending to an IDENTITY field, which I thought was the norm outside of Jet. If find the term unhelpful for many people using Access because they think it's a record number.
David-W-Fenton
I don't see any eveisence to make me think that ANSI-92 Query Mode is anything otehr than native to Jet. I guess we are just going to have to agree to disagree about that one.
onedaywhen
When the documentation says "Jet IDENTITY Datatype" that's explicit and unambiguous to me.
onedaywhen
"There is no choice to cluster" -- sure there is! No one is forcing you to use PK on a table. You should use NOT NULL UNIQUE constraints on all the candidate keys for your table. There's no logical reason to want to 'promte' one of them to 'primary', the reasons are purely physical. The best 'physical' reason I can think of for doing so is clustering (others like to see bold text in Access's Relationships) window. But you always have a choice about clustering but choosing your PK.
onedaywhen
If ANSI-92 is native to Jet, why can't you use it with DAO? It's very clearly the case that ANSI-92 compatibility is provided at a layer above Jet, not within Jet itself.
David-W-Fenton
In re: "Jet IDENTITY Datatype" -- yes, the term is used because the Jet Autonumber is best described with that when speaking of compatibility layers for accessing databases. It is *not* used in Jet's own SQL dialect, nor is it usable in Access itself unless you've turned on ANSI-92 compatibility mode (which by definition is a translation mode).
David-W-Fenton
With Jet, you have no choice to cluster anything other than the PK. This seems to me to be no choice at all in regard to clustering, since the choice of PK is going to be highly constrained by the entity being modelled. Your argument here is like the one that says gay people are not discriminated against when same-sex marriage is prohibited because they can still marry someone of the opposite sex.
David-W-Fenton
Consider a telephone number table. Logical model: phone_number (key), name (not a key, could have dupes). PK only comes in the physical model. Option 1: PK on phone number: bad for Jet because you are performing sequential scans on name yet clustering on phone_number. Option 2: use a UNIQUE constraint on phone_number (the key), use a compound PRIMARY KEY (name, phone_number), use DDL to ensure it clusters on name then phone_number in that order, good for Jet and sequential scans. Two options means you do have choices about clustering and has nothing to do with entity modelling, Q.E.D.
onedaywhen
Trying to correct your analogy to reflect my thinking: more like I'm saying your ethics are outdated by insisting all couples should be married (by implying all tables should have only one key, that all keys should be primary, that primary is superior in the logical model when in fact it does not exist) whereas I am saying that cohabiting, mutual respect, providing a stable home environment for raising children, etc (using NOT NULL UNIQUE in the physical model for all keys) are far more important. Sure, get married if you want to but do it for the right reasons (PK is optional and arbitrary).
onedaywhen
"If ANSI-92 is native to Jet, why can't you use it with DAO?" -- simply put, because DAO is deficient (I though we were agreed on this?) There are many things undeniably native to Jet which cannot be used with DAO: CHECK constraints, WITH COMPRESSION, fixed-width text data types, row-level locking, etc. So you mistakenly equate 'native to Jet' with 'things you can do with DAO'. Try substituting the word 'native' with an expanded phrase and we may attain some clarity here.
onedaywhen
I point out the problems of natural keys when modelling people and you give me an example of a telephone table, which does not have the problem (though it certainly could, given that two people reachable at the same corporate telephone number could have the same name). I don't understand your dismissive comment about the physical model since by the very nature of the discussion (clustering) that's exactly what we're dealing with -- it's the subject of discussion.
David-W-Fenton
The analogy is now strained beyond usefulness, but your conclusion "PK is optional and arbitrary" violates everything I know about relational databases. One of Codd's basic rules was that a field or group of fields should uniquely identify each row. That is a PK to me (even if Codd and Date didn't call it that), and a table without a PK is just a bucket of data without any relational meaning.
David-W-Fenton
DAO is not deficient because of anything other than MS's decision back in 1999 or so to stop updating it because they were intending to replace it with ADO. Circa 2002, MS reversed itself and instead abandoned classic ADO. The end result is that certain aspects of Jet 4 are controllable only through ADO. But that was a political decision on MS's part. DAO *is* Jet's native data access layer even if MS has badly crippled it by not keeping it up to date with the underlying data engine (something that should have been done regardless of whether ADO was intended to replace DAO).
David-W-Fenton
This discussion is going nowhere. You don't seem unawawre of the basics of the interaction between Jet, Access and various data access layers, nor the history of Jet and the corporate intrigues at MS that shaped ADO and its relationship to Jet. This makes useful discussion impossible because you seem unaware that DAO is Jet's native access layer (tied directly to Jet), while ADO is an abstraction layer not tied to any particular database engine (which is its whole reason for existing). DAO is native. ADO is non-native. Period. If you can't agree with that, there's nothing to talk about at all.
David-W-Fenton
I know the history and I know the technologies. What I don't know is what you mean by the word 'native' in the context "DAO is native". Why would you think something external to Jet is 'native' when something internal to Jet (e.g. SQL DDL) is 'non-native'. It makes no sense because you are not showing your working.
onedaywhen
"According to author Chris Date the earliest incarnations of SQL didn't have any key constraints and PRIMARY KEY was only later addded to the SQL standards. The designers of the standard obviously took the term from E.F.Codd who invented it, even though Codd's original notion had been abandoned by that time! (Codd originally proposed that foreign keys must only reference one key - the primary key - but that idea was forgotten and ignored because it was widely recognised as a pointless limitation)." -- http://blogs.conchango.com/davidportas/archive/2006/09/14/Down-with-Primary-Keys_3F00_.aspx
onedaywhen
"a table without a PK is just a bucket of data without any relational meaning" -- a ACE/Jet table with a key defined by NOT NULL UNIQUE but lacking a PK still has a key and the engine will cluster on that key so it is a genuine table and not a heap (what I assume you meant by "bucket"). Whether that key is a 'relational' key depends on the entity being modelled and the columns chosen. An autonumber cannot be a 'relational' key in any sense unless it is exposed to users and everyone advises against that.
onedaywhen
+2  A: 

The statement "If some records are deleted AND the database is compacted the next identity is reset to the lowest used number + 1" is incorrect. This happened in Jet 3.5 used in Access 97 but not Jet 4.0 used in Access 2000.

Tony Toews
I didn't know that, Tony. Thanks for correcting that. I guess I didn't know it because I never care what the Autonumber values are.
David-W-Fenton
@David: why then do you favour incremening over random?
onedaywhen
I prefer incrementing because 1423 is a lot easier to remember than -874036470 when when working on a system and looking at the tables.
Tony Toews
Random Autonumbers are also slower in batch inserts.
David-W-Fenton
@tony: David is correct that you commit a classic flaw: giving meaning to values which are supposed not to be exposed to users and yes that includes power users and developers ;-) You should indeed "never care what the Autonumber values are".
onedaywhen
@onedaywhen <shrug> I stand by my comment.
Tony Toews
@Tony Toews: you are in the minority. If you come with an open mind you could learn something.
onedaywhen
<shrug> I have no idea what a comment such as "keeping on open mind" has to do with preferring short numbers when the developer is looking at raw data trying to figure out some kind of problem.So I still stand by my comment.
Tony Toews
@Tony Toews: I meant that approaching SO with an open mind could result in you learning from your apparent mistakes and modifying your behaviour accordingly. I could be wrong but merely shrugging off advice sounds like someone with a 'closed mind'.
onedaywhen
...One of the things I find advantageous about using natural keys and no surrogates is that the data is more readable. But I can't ask you to change your religion ;-) so if you creat joins back to the referenced table which does hold the natural key's values then you might find your data is more readable and that you no longer need to look at the autonumber values.
onedaywhen
@onedaywhen I once built a system using natural keys. It was much more difficult to work with in the development environment. My mind is not closed, it's just that I don't feel like 1) getting into a religious war 2) I don't feel like articulating in great detail all the reasons why using natural keys are a pain in Access. Because then folks will tell me to be using a different tool. And there's nothing yet that reaches the RAD database capabilities of Access.
Tony Toews
@Tony Toews: "I don't feel like..." Me either, that's why I said, "I can't ask you to change your religion".
onedaywhen
A: 

David W. Fenton wrote: "The Jet Autonumber field is not an identity field. It is only a long integer field with a special default value. That default value can be INCREMENT or RANDOM, but as it is only a default value, you can append any long integer value to the field as long as it doesn't violate the index."

This is a bit confused. ACE/Jet SQL syntax has an IDENTITY keyword (COUNTER, AUTOINCREMENT) but no AUTONUMBER keyword. Clearly an ACE/Jet IDENTITY is an IDENTITY!

But what I want to address here (too long for a comment) is the misstatement about it being "only a long integer field with a special default value".

Consider this ACE/Jet SQL DDL (ANSI-92 Query Mode syntax):

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

When executed, it fails with the message, "Resultant table not allowed to have more than one AutoNumber field". So clearly there is something other than just a "special default value" going on here.

The IDENTITY keyword is creates an autonumber (for want of a better term) with an incrementing algorithm to generate values. IDENTITY cannot be used to create an autonumber with a random algorithm or a GUID (replication ID) flavour of autonumber. For these other cases you do indeed need to use a "special default value" e.g.

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
);

If you use a technology such as ADOX to examine this table's properties (information schema) you'll find that only the column created with the IDENTITY keyword has the Autoincrement property set to true, and this column's COLUMN_HASDEFAULT is false and COLUMN_DEFAULT is null. So if an IDENTITY column does have a "special default value" then the engine isn't telling.

Unlike IDENTITY, with these other flavours of autonumber there is no explicit one per table restriction e.g. this works fine:

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
);

Something I do not know is whether there exists a "special default value" equivalent to GenUniqueID() and GenGUID() to create an auto-increment column using DEFAULT and without using the IDENTITY keyword (or its synonyms). If anyone knows one way or the other, please let me know.

BTW the abovementioned error message suggests I was wrong about 'Autonumber' being an Access term. Seems at the ACE/Jet engine level 'Autonumber' is a non-keyword synonym for IDENTITY (i.e. auto-increment flavour autonumber) but not a synonym for other flavours of autonumber.

onedaywhen
You do realize that when you're using ANSI 92 SQL, you're no longer using Jet SQL? Actual Jet SQL does not have the IDENTITY keyword at all. Secondly, the Jet documentation is built around the assumption that you'll DAO instead of Jet DDL because DAO fully supports all the possible Jet properties of tables and fields, while Jet DDL does not. Your perspective seems to me to not be that of a native user of Jet, but of someone accustomed to working with other db engines.
David-W-Fenton
When using ADOX to read the structure of a Jet able, you're getting back ADOX syntax, not native Jet syntax. Jet Autonumbers behave in many ways like standard IDENTITY fields on other databases. But that doesn't mean they are implemented the same way or behave the same way -- it only means that for some uses, it is a compatible way to treat them.
David-W-Fenton
In summary, if you use non-native interfaces to look at a Jet database, you're not going to get native terminology back, and you may get an imperfect representation of Jet's implementation of particular objects. If you want to know what Jet does, then use native Jet interfaces, i.e., Jet's dialect of ANSI 89 DDL and DAO. Anything else is going to have come to you through a translation layer specifically designed to make all database engines look the same insofar as that's possible.
David-W-Fenton
You are seems to hinge on ANSI-89 Query Mode syntax being the One True ACE/Jet syntax and ANSI-92 Query Mode syntax not being ACE/Jet syntax at all. What would it be, then? It isn't SQL Server syntax. It doesn't work on any engine other than Jet/ACE.
onedaywhen
As you know, the Access interface can be put into ANSI-92 Query Mode but you claim this ins't 'native'. Hmm, this smells real bad.
onedaywhen
"DAO fully supports all the possible Jet properties of tables and fields" -- come off it, you know as well as I do that DAO missed out on the Jet 4.0 feature set. How do you create a Jet 4.0 CHECK constraint using DAO? Compression data types? Fast foreign keys? Row-level locking?
onedaywhen
ANSI-89 is Jet's native mode. That's why it's appropriate to consider it when discussing native Jet terminology. If you're looking at Jet through a translation layer (like OLEDB/ADO, or in Access using ANSI-92 which is there explicitly for SQL Server compatibility, i.e., so you can write NON-NATIVE SQL and use it with both Jet and SQL Server), then you're getting the translation layer's terminology and not Jet's. This is not actually complicated.
David-W-Fenton
ANSI-92 mode in Access is explicitly SQL Server compatibility mode. COMPATIBILITY MODE, not native Jet SQL. And it's not the default and it's used in Access mostly by people who are coming to Access from SQL Server -- i.e., from non-Jet SQL dialects.
David-W-Fenton
You're right about DAO -- Microsoft in the misguided "ADO-everywhere" phase stupidly added support for some new Jet 4 features to ADO but didn't enhance DAO with the same support. I don't know of this has been corrected in A2007/ACE and its new version of DAO, but it would stand to reason that it should be, given that ADO is now deprecated by MS as the interface for Jet/ACE.
David-W-Fenton
In the context I was writing, the comparison was DDL vs. DAO, and no variety of DDL comes anyhere close to supporting the full range of Jet features. To get full support of all Jet features, you have to use DAO supplemented by ADO for the handful of features that ADO supports but DAO does not. But DDL comes nowhere close.
David-W-Fenton
As regards ACE/Jet table columns, if you drew a Venn diagram of the things you can and can't do with DAO, ADO and DLL you the three circles would be virtually concentric, especially if you weighted the features in accordance with their importance i.e. most users most of the time could use any of those technologies and it wouldn't make a bit of difference, its merely a lifestyle choice.
onedaywhen
Consider this ANSI-92 Query Mode syntax: CREATE TABLE T (c1 CHAR(10) WITH COMP, CHECK(1 = (SELECT COUNT(*) FROM T))); c1 has properties a) fixed width, b) UNICODE compression and c) table-level constraint allowing only one row. You can't TRANSFORM it to ANSI-89 Query Mode syntax, DAO or ADO. It only works with the ACE and Jet engines. How can it not be native?!
onedaywhen
ADO is not deprecated for ACE/Jet, neither officially nor de facto. Consider this article: http://support.microsoft.com/kb/240317/en-us. You can't programmatically set these engine properties (and many others) using DAO (even ACEDAO), ditto other properties and DAO. Until you can, ADO will not be deprecated. Anyhow, you've never used it so why would you care? Why would you knock someone else's legitimate 'lifestyle choice' of technology? ADO and DAO are not mutually exclusive!
onedaywhen
@onedaywhen asks: "How can it not be native?!" Native terminology is not the same thing as controlling native functionality via a database interface layer. Jet 4 supports UNICODE, but ANSI-89 SQL DDL does't because it predates its introduction in Jet 4. Again, DDL is the worst possible method of using Jet as it lacks support for almost all the Jet-specific features. Since you are someone who doesn't actually use Access or Jet, this is of no consequence. For the rest of us, it's pretty important.
David-W-Fenton
You are wrong on the Venn diagram. ADO and DAO would largely overlap, with a small bit of ADO unshared by DAO and a small portion of DAO unshared by ADO. DDL would be entirely encompassed by both DAO and ADO, but would be much smaller than the ADO and DAO circles precisely because it lacks support for a large number of features of Jet tables and fields. Here's the way I see it: http://dfenton.com/DFA/images/Venn.png
David-W-Fenton
I didn't say ADO was deprecated. I said ADO as principle data interface to Jet is deprecated. You don't seem to understand the history here. MS pushed ADO as default in Access 2000. They then abandoned it and switched back to DAO as default in A2003, and new work was done on DAO in A2007 and no further work is being done on ADO (not to be confused with ADO.NET, which is a completely different interface and not compatible with Access).
David-W-Fenton
"DDL would be entirely encompassed by both DAO..." -- incorrect e.g. you can't use the DEFAULT keyword in DDL using DAO -- "...and ADO" -- incorrect e.g. you can't create a WITH COMPRESSION column using ADO (or DAO).
onedaywhen
"DDL is the worst possible method of using Jet as it lacks support for almost all the Jet-specific features" -- incorrect in the current context: remember we are taking about creating table columns here. I can only think of a few things in the area that can't be done using DDL but there are close equivalents e.g. there is no DDL syntax to create Validation Rules but there is for CHECK which are more powerful anyhow.
onedaywhen
"Since you are someone who doesn't actually use Access or Jet" -- not currently but I formerly used Jet extensively. Now your turn: you seem to have a good understanding of Jet 3.51 but not so much the features introduced in Jet 4.0 and ACE. I'm right, right? ;-)
onedaywhen