如何编写生成唯一标识符的存储过程?

时间:2011-03-10 13:54:17

标签: c# asp.net stored-procedures

请帮我编写自动生成数字的存储过程,如...

ABC0000001

我们通过asp.net页面创建的每个条目都应该会发生这种情况。我的意思是每次页面加载时都应该创建这个唯一的数字。

6 个答案:

答案 0 :(得分:2)

我已经为需要项目编号或类似内容的各种业务对象做了类似的事情:

declare @maxnum int
declare @myNumber @varchar(32) 
select @maxnum = max(columnName) + 1 from theTable
select @myNumber = 'ABC' + replicate('0', 8 - len(@maxnum)) + cast(@maxnum as varchar)

答案 1 :(得分:0)

我假设您想将此号码存储在某个地方的数据库中?那么这可能是一个Insert存储过程,用于添加新页面吗?

您将不得不将该号码存储在某处,以便存储过程知道下一个号码应该是什么。所以..为什么不将它存储为整数,用uniqueidentifier和identity insert设置它 - 所以你添加的每行都有下一个数字作为ID。

如果你真的需要它在前面有'ABC',那么只要在返回值时将它添加到存储过程中的整数。

答案 2 :(得分:0)

如下所示创建UDF PADL:

CREATE function PADL  (@cSrting nvarchar(4000), @nLen smallint, @cPadCharacter nvarchar(4000) = ' ' )
returns nvarchar(4000)
as
      begin
        declare @length smallint, @lengthPadCharacter smallint
        select  @length = datalength(@cSrting)/(case SQL_VARIANT_PROPERTY(@cSrting,'BaseType') when 'nvarchar' then 2  else 1 end) -- for unicode
        select  @lengthPadCharacter = datalength(@cPadCharacter)/(case SQL_VARIANT_PROPERTY(@cPadCharacter,'BaseType') when 'nvarchar' then 2  else 1 end) -- for unicode

        if @length >= @nLen
           set  @cSrting = left(@cSrting, @nLen)
        else
       begin
              declare @nLeftLen smallint,  @nRightLen smallint
              set @nLeftLen = @nLen - @length  -- Quantity of characters, added at the left
              set @cSrting = left(replicate(@cPadCharacter, ceiling(@nLeftLen/@lengthPadCharacter) + 2), @nLeftLen)+ @cSrting
           end

    return (@cSrting)
   end
GO

您可以使用表来存储当前数字并获取下一个数字,并使用PADL UDF填充所需数量的“0”,然后将“ABC”连接到其中。

答案 3 :(得分:0)

以下示例。您还可以向表中添加请求的日期时间,您还可以传递您要存储的有关请求的其他信息,如引用者,方法等。

create table RequestRecords (
  ixRequestRecord int identity primary key,
  sWhatever nvarchar(max) -- anything else you want to store
)

Create proc WebNewRequestEntry(@sWhatever nvarchar(max)
as
begin
   insert RequestRecords(sWhatever) select @sWhatever
   select 'ABC'+right('00000000000000' + cast(@@IDENTITY_INSERT as varchar(10)), 10) as sRequestRecord
end

答案 4 :(得分:0)

通常我会创建一个“NumberSeries”表,它存储数字系列的名称,最小数量,最大数量,前缀(在您的情况下为ABC)和当前值。然后,为了并发,我将创建以下存储过程:

CREATE PROCEDURE [dbo].[spGetNextNo]
    @series NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;

DECLARE @prefix NVARCHAR(10)
DECLARE @result NVARCHAR(50)
DECLARE @currvalue BIGINT
DECLARE @maxvalue BIGINT
DECLARE @errmsg NVARCHAR(250)   

-- Find max value for number series
SELECT @prefix = Prefix, @maxvalue = EndValue FROM NumberSeries WHERE Series = @series
IF (@maxvalue IS NULL)
BEGIN
    SET @errmsg = 'Number series "'+@series+'" does not exist!'
    RAISERROR(@errmsg, 16, 1)
    RETURN
END

-- Create next number
DECLARE @MyTableVar TABLE (CurrValue BIGINT)
UPDATE tNumberSeries
SET
    CurrentValue = CurrentValue + 1
OUTPUT INSERTED.CurrentValue INTO @MyTableVar
WHERE
    Series = @series

-- Number series used up?
SELECT TOP 1 @currvalue = CurrValue FROM @MyTableVar    
IF (@currvalue >= @maxvalue)
BEGIN
    SET @errmsg = 'Number series "'+@series+'" is used up!'
    RAISERROR(@errmsg, 16, 1)
    RETURN
END

SET @result = CAST(@currvalue AS NVARCHAR)
IF @prefix IS NOT NULL
    SET @result = @prefix + @result

-- Return prefixed result
SELECT @result AS CurrentValue
RETURN 0

END

UPDATE/OUTPUT语句确保当前值以并行呼叫者在任何情况下接收唯一号码的方式增加。

答案 5 :(得分:0)

您应该向包含此字段的表格添加支票 - constraint

([ABC_Number] IS NOT NULL AND len([ABC_Number])=(10) AND substring([ABC_Number],(1),(3))='ABC' AND substring([ABC_Number],(4),(7)) like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9]')

通过这种方式,您可以确保无法从某处注入具有无效唯一标识符格式的记录。

一个唯一约束,以确保表中的数字不重复:

[dbo].[_CountAbcNumber]([abc_number])<(2)

其中_CountAbcNumber是这样的udf:

CREATE FUNCTION [dbo].[_CountAbcNumber](
    @AbcNumber AS nchar(10)
)

RETURNS int AS BEGIN
    declare @retVal int

   select @retVal = max(occurrences)
   from ( 
        select ABC_NUMBER, count(*) as occurrences
        from dbo.YourTable            
        where ABC_NUMBER = @AbcNumber
        group by ABC_NUMBER
   ) tmp
   return @retVal;
END