I have a a business requirement that each record in the Invoice table has an id which looks like YYYYNNNNNN.
The NNNNNN part needs to restart at the beginning of each year. So the first row entered in 2016 would look like 2016000001 and the second like 2016000002 etc.
Lets say the last record for 2016 was 2016123456, The next row (of 2017) should look like 2017000001
I don't need this id to be the primary key and I store the creation date as well. The idea is that this 'display id' is unique (so I can query by it) and human group-able, by year.
It is unlikely that any records would be deleted; however, I would be inclined to code defensively against something like that.
Is there any way I could create this id without having to query for the max id this year every time a insert a new row?
Ideas:
- A
CreateNewInvoiceSP
, which gets theMAX
value for that year (yucky) - Some magical built in feature for doing exactly this (I can dream right)
- Being able to specify some UDF or something in the
IDENTITY
orDEFAULT
declaration (??) - A view which uses
PARTITION OVER + ROW()
(deleted would be problematic) - A trigger on
INSERT
(would still need to run someMAX
query 🙁 ) - An annual background job, updated a table with the MAX for each year inserted which I then… Something?!
All of which are a bit non ideal. Any ideas or variations welcome though!
Best Answer
There are are 2 elements to your field
They do not need to be stored as one field
Example:
YEAR(GETDATE())
Then create a computed column concatenating them (with appropriate formatting). The sequence can be reset on change of year.
Sample code in SQLfiddle:*(SQLfiddle doesn't always work)