SQL Server 2008 identity Key auto increment Issue - sql

I recently had to move a database(sql server 2008) to a different server, and I have noticed that in one of the table, the value of identity column has started to get some unexpected values. its set as identity column with identity increment 1 and identity seed 1. After every 10 consecutive entry or so, it would start from another much higher number and increment by 1 for next 10 entries or so and then jump up to another higher number. I can't seem to figure out the issue.
Sorry for the layman language. I am not a DB person.

This is likely not an issue with your identity key but an issue with a framework being used to insert data, or a SP. If you have a stored procedure that inserts data but then is ROLLBACK'd, the ID was reserved but the row is 'deleted'.
So two places to check: One on the frameworks you're using (NHibernate, or Entity Framework, etc?)... those frameworks might be inserting rows then deleting them. Second place to check is INSERT statements in SPROCs and other places you might expect a ROLLBACK.
See: SQL Identity (autonumber) is Incremented Even with a Transaction Rollback
Another issue is that you may just be examining data without sorting it? And when you ported the data you assumed it would be inserted or retrieved always in-ID-order. But because the new table is not 'indexed' the same way you won't necessarily see items in primary-key order. This is less likely if rows appear sequential most of the time with gaps, but worth mentioning.

The following will shed some light on your issue.
Create a table with an identity auto increment column
Insert 10 rows of random data
You will see that the ID values are 1,2,3,4,5,6,7,8,9,10
delete from mytable where id=10
insert another row into the table
now you will see the ID values are 1,2,3,4,5,6,7,8,9,**11**

Related

Can you insert a custom value in an Auto-incrementing field in MS Access

The column auto-increments. User wants to insert a row with a specific number (I've confirmed it doesn't already exist in the column). In SQL Server I'd do a quick SET IDENTITY_INSERT ON and insert statement. Is there a way to this for Microsoft Access or are they just out of luck.
Can run an INSERT action SQL.
But then need to Compact & Repair to reset the autonumber seed. Or, per #4dmonster comment, run another INSERT with the maximum autonumber value already in database. As long as the autonumber is set for unique index, the insert will fail but sequence will be fixed and normal data entry will generate next number. I tested and it worked.
I can only guess this autonumber is used as a sequential number that must be accounted for, as in a license number series. Otherwise, sequence gaps should not be a concern and can be ignored.
NotAn answer, but a workaround. Don't make the column autoincrement, but set the default value to max current values plus one. The defualt will, in effect, step up by one, but the user can pick a different value. Has not been tested on very large tables.

Reuse the deleted row's identity value

Is it possible to reuse an identity field value after deleting rows in SQL Server 2008 Express? Here is an example. Suppose I have a table with an Id field as a primary key (identity). If I add five rows, I will have these 5 Ids: 1, 2, 3, 4, 5. If I were to delete these rows, and then add five more, the new rows would have Ids: 6, 7, 8, 9, 10. Is it possible to let it start over at 1 again?
Do I have to delete data from another table in order to accomplish this? Thanks for your help.
Is it possible to reuse an identity field value after deleting rows in SQL Server 2008 Express?
Yes, but it's one of the worst decisions you could make.
This is so bad that I'm not gonna explain how to do it, but just why this is bad.
We use identity columns to generate values that are unrelated to the data the table holds.
If we use identities as primary keys and we reuse their value, the same key will hold 2 (or more) different entities throughout time, giving place to confusion specially when generating reports or having other tables that use this key and don't have referential integrity.
Solutions used to identify unused values (infamous gaps and islands problem) are very slow when the amount of rows increase. This makes performance drop as rows piles up.
You will have to apply this "unused number" logic every time you insert rows on the table, so it's another thing to keep in mind on maintenance tasks.
There is little to none benefit of reusing these numbers as INT or BIGINT max values are high enough to support most business data.
It's common to use identities as primary keys or with a clustered index because new records will be inserted at the end, reducing fragmentation. Once records are deleted, it generates gaps in between pages (the swiss cheese pages), which is solved by doing index rebuilds. The problem comes after the rebuilds, where you will be potentially inserting new records massively in between and cause tons of page splits, hitting performance unnecessarily.
I can't possible think of a real case when you actually need to fill empty gaps in an identity column, as the purpose of this value is to be unrelated to the entity the table represents.
If you are going to remove all the data inside the table you can use TRUNCATE TABLE, which will help you remove whole data in table and reset the identity to start from the SEED value.
TRUNCATE TABLE MyTable
You can also use DBCC CHECKIDENT to reseed your identity to the spesific value.
DBCC CHECKIDENT ('dbo.MyTable', RESEED, 1);
The following code will reed the identity to start from 1.
Finally, if you need to cover the gaps, you need to know that, using IDENTITY you are mot able to cover the gaps, and you need to implement your custom function to behave like IDENTITY and cover the gaps.
We can do this by two ways.
If it is Non Pk Column, Insert the record with same Identity number then delete the previous identity column value.
If you don't need owl data drop the table and recreate that table or truncate the table and use DBCC CHECKIDENT to reseed your identity to the spesific value.
Possible if you remove Autoincrement attribute from ID.
You can keep a check if the table is empty or not and INSERT values accordingly.

How to check who has RESET the Identity column value on a table in SQL server 2008

A table was running with identity value in 100s few days back. When I inserted a new record suddenly it picked 1106 as value. Need to know who has reset the identity value on that table. Don't think there is a possibility of insertions and deletions on this table.
identity columns do not guarantee perfectly incremental values on every insert. It is most likely that no one has touched your table. If you are relying on this value being incremental, you should read up on the specs and redesign your database.

Questions about increment operator

I have a table with a field that increments. The values for that field are 1, 2, 3...60 and then the field is 1060.
I don't know why?
The next value for id must be 61.
This is a new feature of SQL Server 2012. Identity columns use Sequences and values are cashed by default to speed up when inserting new rows. When unplanned shutdown of SQL Server occurs, cache is lost and Identity values continue with gap (of usually 1000 or 10000) created.
There could be several reasons - some of the most likely:
999 records were deleted
999 inserts were attempted and failed
Something reset the identity value using DBCC CHECKIDENT ({table}, RESEED, {value});
Something inserted a record with a specific ID using SET IDENTITY_INSERT ON
Autoincrement fields are not guaranteed to be consecutive. Thy are guaranteed to be unique. If you need them to be consecutive, then I would recommend keeping track of the next ID yourself, which will require you to think about concurrency, foreign key references, etc.
Am assuming you mean an IDENTITY field with an increment of 1.
This increases the value by 1 each time a new record is inserted.
To quote:
If an identity column exists for a table with frequent deletions, gaps
can occur between identity values. If this is a concern, do not use
the IDENTITY property. However, to ensure that no gaps have been
created or to fill an existing gap, evaluate the existing identity
values before explicitly entering one with SET IDENTITY_INSERT ON.
As alluded to in the comments it's likely this table once had data populated with all the missing values but these were deleted. (As this is quite a big chunk maybe this was done in bulk?)

DB2 auto increment changed by itself after restarted

Each time I restart my DB2 services, the auto increment field, always change by itself,
for example : before I restart, the auto increment value is at 13, and it's incremented by 1, and after I restart it's always become 31 and it's always incremented by 20
Any idea what may cause this?
Each time I restarted my Db2 service, I have to execute this command
ALTER TABLE <table> ALTER COLUMN <column> RESTART WITH 1
DB2 has a cache of generated values in order to reduce the overhead of generating values (Reduce the IO). This cache in memory, and assign the values as requested.
Take a look at the cache option when creating / altering the table. By default the cache value is 20.
It is important to understand how the sequeneces work in DB2. Sequences share many concepts with generated values / identity column.
Create table http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000927.html
Alter table http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000888.html
Sequences http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.admin.dbobj.doc/doc/c0023175.html
From W3schools:
"Auto-increment allows a unique number to be generated when a new record is inserted into a table."
This is the only thing you may expect: unique (=non-conflicting) numbers. How these are generated is left to the DBMS. You must not expect a number sequence without any gaps.
For instance, a DBMS might choose to "pre-allocate" blocks of ten numbers (23..32, 33..42, ...) for performance reasons, so that the auto-increment field must only be incremented for every (up to) ten records. If you have an INSERT statement that inserts only 5 records into a newly created table, it can "acquire a block of 10 numbers" (0..9), use the first five values (0..4) of it and leave the rest unused. By acquiring this one block of numbers, the counter was incremented from 0 to 10. So the next INSERT statement that fetches a block will get the numbers ranging from 10 to 19.