Я сохраняю документы в базе данных, каждый документ должен иметь идентификатор в формате YYYY-00000:
- первые 4 символа - текущий год
- вторые пятьсимволы цифры.Они начинаются с 1 каждый год, а затем увеличиваются.
Например, у меня могут быть эти документы в моей базе данных: 2011-00001, 2011-00002, 2011-00003, 2012-00001, 2012-00002,...
Я думаю, что-то вроде этого:
- добавить два столбца в таблицу Документы (год и номер)
- Год вычисляемый столбец, что-то вроде
year(getdate()
) - Число - это вычисляемый столбец, который получает значение из функции
GetNextNumberForCurrentYear
- GetNextNumberForCurrentYear возвращает следующий номер для текущего года (например,
select max(Number) + 1 from Documents where Year = year(getdate())
и некоторая проверка нуля)
Но я боюсь, что два пользователя могут захотеть сохранить документ одновременно и получить один и тот же номер.Это возможно?Есть идеи получше?
Это веб-приложение ASP.NET C #, .NET 4.0, MSSQL 2005, у меня есть контроль над всеми частями приложения.
PS: после вставки яхотел бы вернуть идентификатор нового документа пользователю, поэтому мне, вероятно, придется сделать что-то вроде: select Id from Documents where SomeId = scope_identity()
, поэтому я предполагаю, что где-то должен быть столбец идентификаторов ...?
Edit (окончательное решение): я получаю следующий номер из хранимой процедуры, строю Id документа (в формате YYYY-00001) в .NET, сохраняю весь документ в базу данных (используя TransactionScope для всего процесса), а затем возвращаю Id вПользователь.
create table DocumentNumbers ([Year] int not null, Number int not null default 1)
insert into DocumentNumbers ([Year], Number)
select 2012, 1 -- and more...
create procedure GetNextDocumentNumber
@year int
as
begin
declare @myResult table (nextNumber int)
update DocumentNumbers
set Number = isnull(Number, 0) + 1
output inserted.Number into @myResult
where [Year] = @year
select top 1 nextNumber from @myResult
end