我将文档保存到数据库,每个文档都必须有一个格式为YYYY-00000的id:
例如,我可以在我的数据库中包含这些文件:2011-00001,2011-00002,2011-00003,2012-00001,2012-00002,......
我在想这样的事情:
year(getdate()
)GetNextNumberForCurrentYear
select max(Number) + 1 from Documents where Year = year(getdate())
,有些是无效检查)但我担心,两个用户可能希望同时保存文档,并且他们会收到相同的号码。这可能吗?有更好的想法吗?
它是一个ASP.NET C#Web应用程序,.NET 4.0,MSSQL 2005,我可以控制应用程序的所有部分。
PS:插入后我想将新文档的Id返回给用户,所以我可能需要做类似的事情:select Id from Documents where SomeId = scope_identity()
,所以我想在某处应该有一个标识列。 ?
编辑(最终解决方案):我从存储过程中获取下一个数字,在.NET中构建文档的Id(格式为YYYY-00001),将整个文档保存到数据库中(使用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
答案 0 :(得分:2)
您可以创建一个表NumberSeries
,其中包含一列Year
和一列CurrentNo
以及一个返回下一个数字的函数,如下所示:
DECLARE @myResult TABLE (nextNumber INT)
UPDATE NumberSeries
OUTPUT INSERTED.NextNo INTO @myResult
SET
CurrentNo = ISNULL(CurrentNo, 0) + 1
WHERE
Year = Year(GetDate())
DECLARE @result INT
@result = (SELECT TOP 1 nextNumber FROM @myResult)
RETURN @result
以原子方式更新NumberSeries
表,并将新值插入@myResult
表变量中。之后,它返回@myResult
表变量中的第一个(也是唯一的)值。
其他所有内容,例如SCOPE_IDENTITY()
等,在使用触发器时可能会导致错误,或者在其他情况下 - 使用OUTPUT
子句的解决方案是安全的。
修改强>
至于返回插入文档的ID:这基本上是一样的。
DECLARE @myDocId TABLE (yr int, no int)
INSERT INTO Documents
OUTPUT INSERTED.Year , INSERTED.YearID INTO @myDocID
...
SELECT TOP 1
CAST(yr AS NVARCHAR) +
'_' +
RIGHT(REPLICATE('0', 5) + CAST(no AS NVARCHAR), 5) AS NewID