views:

77

answers:

4

I have use Identity on ID primary key. And then I insert some data. For example.

Data 1 -> Add Successful without error. ID 1

Data 2 -> Add Successful without error. ID 2

Data 3 -> Add Fail with error.

Data 4 -> Add Fail with error.

Data 5 -> Add Successful without error. ID 5

You can see that ID has jump from 2 to 5.

Why ?? How can solve this ??

A: 

hi,

this is by design, sql server first increments the counter and than tries to create row, if it fails transaction (there is implicit transactions always) is roll backed but auto increment value is not reused. this is by design and I would be very surprised to see that it can be avoided (eventually you could call some command and reset the value to current maximum). You can always use the trigger to generate this values, but this has performance implications, usually you should not care about the value of auto_increment its just an integer, you would have the same situation later in your application if th

zebra
+2  A: 

Why would that be a problem ?

Normally, you'll use an identity in a primary key column. Then, this primary key is a surrogate key, which means that is has absolutely no business value / business meaning. It is just an 'administrative' fact, which is necessary in order that the database can uniquely identify a record. So, it doesn't matter what this value is; and it also doesn't matter that there are gaps. Why do you want them to be consecutive.

And, suppose that they are consecutive -that no gaps appear when an insert fails- what would you do when you delete a row, and insert one later on ? Would you fill in the gaps as well ?

Frederik Gheysels
Accountants freak out when they see a gap in IDs :) They think a record existed, but was maliciously erased somehow.
Seva Alekseyev
The accountant should never see that ID, since it is just something used inside in the DB, and has no business meaning.And don't tell me that the accountant has direct access to the database. :)
Frederik Gheysels
If it's a transaction ID, they do see it. Unlike the normal user population, accountants do very much care for unique, numeric IDs of their stuff.
Seva Alekseyev
Accountants do care for unique, numerical values. These values are not row identifiers though. They are Invoice Numbers, or General Ledger Account Numbers, or other meaningful values. Meaningless row identifiers, like other internal constructs such as indexes, constraints, stored procedure logic, etc. are not presented to the accountants.
JeremyDWill
Yes, but would you introduce an alternative numbering system for invoices, when an identity column in the invoice table gives you a 99%-gap-free numbering?
Seva Alekseyev
Yes, I would definitely introduce an alternative numbering system. Identity columns have no place in user data whatsoever. They allow the application(s) to find rows - nothing more. Overloading them with meaning creates nothing but problems.
JeremyDWill
@Seva: yes; since the business may require that an invoice-number looks rather different then just a number. The database should not generate invoice-numbers, the business layer should do that.
Frederik Gheysels
A: 

If an insert failed, you can, for the next insert, use *set identity_insert mytable on* and calculate the next identity by hand, using max(myfield)+1. You might have concurrency issues though.

But this is a cludge. There's nothing wrong with gaps.

Seva Alekseyev
A: 

@Frederik answered most of it -- I would just add that you are mixing up primary keys and business keys. An invoice (or whatever) should be identified by an invoice number -- a business key which should have a UNIQUE column in the table. The primary key is here to identify a row in the table and should be used by the database (to join ..) and by DBAs only.

Exposing primary keys to business users will end up in trouble and the database will sooner or later lose referential integrity -- always does, people are creative.

Damir Sudarevic