Can Autoincrement field ever use the same value twice? - ms-access

I have a table1 with an id field, type AutoIncrement. I need to copy the entire record from table1 into table2 if there is no record with the same id in table2. Then I delete the record from table1.
I need to know that if table1 gets new records, the id field will never be a number that was ever used before. Does this happen automatically, or do I need to do something to ensure this?
I tried deleting some records and adding new ones, and it really didn't use the same id, but I'm not sure that this is what always happens.

It is possible to duplicate numbers in autoincremet field quite easy, but normally applications don't work this way.
Access remembers last inserted value in autoincrement field and uses it for calculating next value. You cannot insert particular value into autoincrement field using table designer or recordset in VBA, but it's possible if you use INSERT SQL statement. So, if autoincrement field has no unique index, you can insert any value. Also if you insert value less than maximum existing number, Access will generate duplicates automatically.
So I would not recommend rely on unique autoincrement numbers without unique index.
INSERT SQL can be used for resetting numeration without dropping field/table, just run query like this in query builder or using VBA:
INSERT INTO Table1 ( id ) SELECT 1;
This is table with autoincrement field ID I just created:

it is really so, Auto-increment fields in MS Access are always incremental, even if records are deleted, database compacted, etc.
The proposed number can be reset deleting the auto-increment field, perform the copy of the table and then adding the auto-increment field again.

Auto increment never uses the same # even though it's deleted from the table.
It requires complete reset so that it will start from the base and create new #.

Related

Why do my sql tables maintain deleted id's?

When I insert data into a brand new table, it will assign a new id via AUTO_INCREMENT. So the first time I perform an insert I get an id of 1. However, if I delete the row and insert new data, the table acts as if there is still a preceding row (the new row will have an id of 2). This behavior concerns me because I feel like the data is still persisting somewhere. Any ideas of what it could be?
Your data is not persisting. MySql maintains a separate table about your table containing, among other things, the next auto-increment value for your table. You can reset this with:
ALTER TABLE tablename AUTO_INCREMENT = 1
However, be aware that if you are resetting to a value below another valid value in the table, you're asking for trouble.
you should simply use.
truncate table tablename;

MySQL SELECT DISTINCT rows (not columns) to filter $_POST for duplicates

I'm trying to filter rows from the MySQL table where all the $_POST data is stored from an online form. Sometimes the user's internet connection stalls or the browser screws up, and the new page after form submission is not displayed (though the INSERT worked and the table row was created). They then hit refresh, and submit their form twice, creating a duplicate row (except for the timestamp and autoincrement id columns).
I'd like to select unique form submissions. This has to be a really common task, but I can't seem to find something that lets me call with DISTINCT applying to every column except the timestamp and id in a succinct way (sort of like SELECT id, timestamp, DISTINCT everything_else FROM table;. At the moment, I can do:
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS (
SELECT DISTINCT everything,except,id,and,timestamp
FROM table1
);
SELECT * FROM table1 LEFT OUTER JOIN temp1
ON table1.everything = temp1.everything
...
;
My table has 20k rows with about 25 columns (classification features for a machine learning exercise). This query takes forever (as I presume it traverses the 20k rows 20K times?) I've never even let it run to completion. What's the standard practice way to do this?
Note: This question suggests add an index to the relevant columns, but there can be max 16 key parts to an index. Should I just choose the most likely unique ones? I can find about 700 duplicates in 2 seconds this way, but I can't be sure of not throwing away a unique row because I also have to ignore some columns when specifying the index.
If you have a UNIQUE key (other than an AUTO_INCREMENT), simply use INSERT IGNORE ... to silently avoid duplicate rows. If you don't have a UNIQUE key, do you never need to find a row again?
If you have already allowed duplicates and you need to get rid of them, that is a different question.
I would try to eliminate the problem in the first place. There are techniques to eliminate this issue. The first one on my mind is that you could generate a random string and store it in both the session and as a hidden field in the form. This random string should be generated each time the form is displayed. When the user submits the form you need to check that the session key and the input key matches. Make sure to generate a different key on each request. Thus when a user refreshes the page he will submit an old key and it will not match.
Another solution could be that if this data should always be unique in the database check if there is that exact data in the database first before inserting. And if the data is unique by lets say the email address you can create a unique key index. Therefore that field will have to be unique in the table.

How to control auto increment id?

I have an entity with a strategy to auto generate an id based on an integer column in MySQL. Things work, but while testing exceptions and related rollbacks, I noticed that MySQL does not reset last incremented value.
So a successful save produces entity id 1
An attempted save gets entity id 2 but is rolled back.
Then a successful save of a new entity gets entity id 3.
Consequently, in the table we have two records. One with id 1 and the other with id 3.
Are there any ways to control this? Basically, in the scenario I have just described, I would like to see two entities: one with id set to 1 and the other with id set to 2.
No, you can't change that. That is how it is supposed to be.
An auto-increment id has to be unique. That's all.
Auto-increment numbers have to be unique, but they don't have to be consecutive. They are monotonically increasing only as a coincidence of their implementation.
You can always insert a specific value and bypass the auto-increment mechanism. But you'd have to know what value is the "next" value. To avoid race conditions, you'd have to lock the table, query the MAX(id)+1 and then insert that value.
And that's exactly what MySQL would have to do, too, if it were to do this automatically.
The way auto-increment works now allows maximum concurrency without race conditions. So it is by design that it "loses" some values from time to time, when you rollback an INSERT, or else if you subsequently DELETE a value.
You can handle it using your own auto increment logic.
Have a Max+1 idgenerator or have a table that maintains PK auto generated IDs of such tables.
A table like this
LastKey TableName
1 TableX
5 TableY
Everytime, you will have to query from this table to get the incremented id.

How does MySQL Auto Increment work?

I was just creating a new table using MySQL Query Browser, and noticed there's a tick under Auto Increment Column. How does that work?
When adding to the database programatically, do I just add a number, and then the database automatically increments that number?
Everytime a NEW user registers on my site, I want their Customer ID (integer only) to auto increment, so I don't have to try and randomly generate a unique number.
Can this be done simply?
Thank you!
When adding to the database programatically, do I just add a number, and then the database automatically increments that number?
Yes, that's the way auto_increment works.
The value will be incremented for each new row
The value is unique, duplicates are not possible
If a row is deleted, the auto_increment column of that row will not be re-assigned.
The auto_increment value of the last inserted row can be accessed using the mySQL function LAST_INSERT_ID() but it must be called right after the insert query, in the same database connection
mySQL Reference
1 more,
You can insert your own value also (ie your random value).
Yes. Auto_Increment columns work like they say on the tin. Tips
when INSERT - ing, use NULL or omit the column
Use LAST_INSERT_ID() (or API equivalents) to obtain the last generated value.
for security and business logic reasons, it's usually better form to not directly use a key value for a customer identifier. Consider using Hashed / randomised surrogate customer keys instead.
Ta
Yes, that's the exact purpose of AUTO_INCREMENT. It looks at whatever is the current increment value for that table, and stores that value plus 1 for the new row that comes in, automatically. You can omit that field from your INSERT statements and MySQL will handle it for you for every new row that comes in, giving each row its own unique ID.
When you enable Auto Increment an ID will always get automatically added whenever a new record is made.. Example:
If you have 1 record with ID 1 in your table and you add a new record, the ID will automatically be 2.

MS Access autonumber problem

A client of mine accidentally deleted about 500 records from an access table that has a primary ID field which was created as "autonumber". By turning off the autonumber column (changing back to a integer), I was able to restore the missing 500 records from a backup, but now of course the autonumber cannot be turned back on...
What are some possible solutions? The ID field is used as a link to other tables, so I can't just renumber everything without also renumbering all of the tables that reference this number (a pain in the neck, but possible).
Is there any "trick" to turning autonumber back on, using the max(id) as the starting point if data already exists in the table?
Make newTable with ID field as AutoNumber (all fields must be same as in original table - except ID). Copy all data from originalTable to newTable:
INSERT INTO newTable SELECT * FROM originalTable
Once data is filled, delete originalTable and rename newTable to originalTable.
This way all "holes" in auto-numbering are preserved and newTable has Auto-Numbering turned on.
P.S. Always try to add foreign keys to your IDs. In that case, even if some data is deleted, you will at least have consistent state.
The ideal solution, although it's now too late, wouuld've been to restore the missing 500 records into a working table. Then do an Append query into the main table. This would've included the Autonumber field.
If I could add to the answers given.
A little known fact about Access autonumber fields is that the counter on them is reset when you compact and repair the database.
I am also pretty sure that if you do an insert it WILL use the numeric that is supplied rather than the next number in the autonumber counter as long as it is > (greater than) the internal counter kept by the auto-number field (does that make sense at all?)
In other words you CAN do something like this in an brand new access table where the counter should be set to 1...
INSERT INTO myTable (myAutoNumber,myOtherField) VALUES (10000,'other data')
The other solutions mentioned here are better because they would do a better job of guaranteering the result so I mention it almost for academic reasons.
Seth
Agree, but may want to add an ORDER BY to ensure that the AutoNumber is in the correct order. Otherwise your other tables will have the wrong ID association.
INSERT INTO newTable SELECT * FROM originalTable ORDER BY ID
You will also have to explicitly name the fields instead of using *
You make a new field and make it auto-number and then delete id field and rename new field to id