C# 如何编写生成唯一标识符的存储过程?
请帮助我编写自动生成数字的存储过程,如C# 如何编写生成唯一标识符的存储过程?,c#,asp.net,stored-procedures,C#,Asp.net,Stored Procedures,请帮助我编写自动生成数字的存储过程,如 abc000001 它应该发生在我们通过asp.net页面所做的每个条目上。我的意思是,每次加载页面时,它都应该创建这个唯一的数字。我假设您想将这个数字存储在数据库的某个地方?这可能是一个插入存储过程,用来添加一个新页面 您必须将数字存储在某个位置,以便存储过程知道下一个数字应该是什么。所以..为什么不将其存储为整数,使用uniqueidentifier和identity insert设置它-这样您添加的每一行都有下一个数字作为ID 如果确实需要在前面加上
abc000001
它应该发生在我们通过asp.net页面所做的每个条目上。我的意思是,每次加载页面时,它都应该创建这个唯一的数字。我假设您想将这个数字存储在数据库的某个地方?这可能是一个插入存储过程,用来添加一个新页面 您必须将数字存储在某个位置,以便存储过程知道下一个数字应该是什么。所以..为什么不将其存储为整数,使用uniqueidentifier和identity insert设置它-这样您添加的每一行都有下一个数字作为ID
如果确实需要在前面加上“ABC”,那么在返回值时,只需将其添加到存储过程中的整数中即可。创建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”合并到其中。下面的示例。您还可以将请求的日期时间添加到表中,还可以传递希望存储的关于请求的其他信息,如引用人、方法等
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
通常我会创建一个“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
语句确保以某种方式增加当前值,使并行调用方在任何情况下都能收到唯一的号码。我为需要项目号码或类似号码的各种业务对象做过类似的事情:
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)
应在包含此字段的表中添加一个复选框:
([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)
请更新你的帖子,把你到目前为止所写的内容包括在内。为什么它的正面需要“ABC”,正常的身份有什么问题?如果您需要一个额外的代码来进行隔离,则将其单独存储,并在视图中以串联方式返回。@Cheta,一个“like”数字“abc000001”是“xyz000001”。。。您至少需要描述您试图生成的模式。一个例子并没有描述一个模式,为什么需要数据库呢?您不能使用ASP.NET应用程序变量或会话本身来执行此操作吗?至少告诉我们您正在使用哪个数据库。目前,似乎每个人都在猜测SQL Server:)
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