tags:

views:

47

answers:

2

I have a table with 2 primary keys (int, int) and was wondering if it was possible to have one of the primary keys set to auto increment and the other not? The following is the basics of the table structure:

Table
{
   Id - Int,
   VersionId - Int
}

Basically I have an Id with a Version so that there is a complete history of that record and therefor can be rolled back at any time.

I want to be able to insert and Id and for it to then automatically handle the version number for me. Is this possible?

Thanks in advance.

+2  A: 

You can create the compound PK but the version incrementing won't work as you expect - it will be continuous and not 'reset' to version 1 on every new ID

create table SomeTable
(
  id int not null,
  version int identity(1,1) not null,
  primary key(id, version)
)

insert into SomeTable(id) values (1234)
insert into SomeTable(id) values (1235)
insert into SomeTable(id) values (1234)

select * from SomeTable

Returns

1234 1
1235 2
1234 3

etc

nonnb
For display purposes `select id, row_number() over (partition by id order by version) as p_version from SomeTable` could be used to get a more intuitive version number.
Martin Smith
+2  A: 

No, SQL Server has no such "partitioned" identity concept. If you really need this (really??) then you have to provide this programmatically, somehow (from your client, or by handling it yourself in SQL Server using a helper table or something like that).

You can have an IDENTITY field - but that's a consecutive INT number over your whole table - not consecutive for each Id. On the other hand, since that IDENTITY will be unique and ever-increasing, you can use that as a version field, too (it's not going to be 1, 2, 3 for each ID - but the sequence is still there).

In that case, you might have

ID    Version
 1        1
 2        2
 3        3
 1        4

and so forth.

marc_s
@marc_s - Looks like a perfectly valid structure to me, what's with the `really??`?
GenericTypeTea
yes i really do need it, how else would you implement versioning? thanks for you help though, will just have to continue manually handling it within the stored proc :)
Secret Squirrel
@GenericTypeTea: yes, at first sight, it looks like a perfectly valid structure. BUT: it's really hard to implement this properly and with good performance - and the IDENTITY field already offers all those benefits - just not "1,2,3...." for each individual ID. So that begs the question: how much effort do you want to put into having consecutive numbers for each ID, if another solution is already there and is "for free" - just use it.....
marc_s
@marc_s - What about an invoicing system (I've written one in the past and I used a structure similar to this). You've got a product with a product code, say `XYZ` and it has a number of versions, so the structure becomes: `ID:XYZ Version:0`, `ID:XYZ Version:1`, etc. This allows an invoice to have many products and for future changes to a product to not affect previous invoice item descriptions, costs and values, etc... Was this wrong, or is there a better way?
GenericTypeTea
@GenericTypeTea: it can make sense to have such a scheme - its just a lot more work to get it to function properly and scale well than most project lead and business folks might imagine. And often it's really not needed - a simple IDENTITY will do just fine - which is available for virtually no effort at all.
marc_s