生成6位数的唯一编号

时间:2013-03-11 21:38:24

标签: sql-server

编辑:它将用作员工唯一编号(必须按随机顺序)

我有一个列

的表
id(auto-increment), uniqueNumber, and some other field

对于每个插入的记录,我想为uniqueNumber生成一个6位数的唯一编号,

现在我通过触发器

获取此信息
Create TRIGGER [dbo].[trgUniqueCode] ON [dbo].[testtable]
FOR INSERT
AS
declare @id int;
DECLARE @Upper INT
DECLARE @Lower INT
declare @result int
select @id=i.id from inserted i;
SET @Lower = 100000 
SET @Upper = (select top 1(isnull(UniqueNumber,999999)) from testtable) 
set @result =(ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0))
update testtable set UniqueNumber = @result where ID=@id

我不确定这个方法是否有效,我正在寻找最佳的生成方法(优先时间执行),或者我将在C#中生成唯一的数字?

8 个答案:

答案 0 :(得分:7)

生成尚未分配的所有号码的列表。随机播放列表并创建一个包含随机ID和递增索引的新表。当您需要新ID时,请选择索引最小的ID;将其从未使用的ID表中删除,并将其作为新ID返回。

答案 1 :(得分:2)

编辑:哎呀,错过了“必须是随机顺序”的要求。对于那个很抱歉。

对此,我建议采用完全不同的方法解决问题。我认为你应该推迟“必须随机”的业务要求。这是为了什么?

根据我的经验,这通常是因为管理人员不希望像“爱丽丝的爱丽丝的员工身份是1987年,所以鲍勃必须是1988年”这样的场景。我对此的回答是“那么什么?”。了解Bob的员工ID不应该帮助攻击者 - 如果确实如此,那么组织的安全性就会出现更大的问题。

在实施上述优秀答案的过程中,需要考虑并试用。

我的原创,错误,回答:

为什么不使用自动增量字段?

在SQL Server中,按如下所示创建列。

create table dbo.Whatever (
    id int not null identity( 100000, 1 ) ,
    …

您还应该创建主键约束或唯一约束来强制执行唯一性,也可以创建检查约束来强制执行下限和上限(分别为100000和999999)。

create table dbo.Whatever (
    id int not null identity( 100000, 1 ) 
        constraint id_u unique 
        constraint id_bounds check ( id between 100000 and 999999 ) ,
    …

这绝对必须是一个6位数字吗?您可以使用其他地方建议的uniqueidentifier吗? NEWID()函数意味着您不会遇到尝试同时为多个会话生成唯一编号的序列化问题。

答案 2 :(得分:1)

的Transact-SQL:

select floor(rand()*1000000-1)

C#:

Random rnd = new Random();
int rslt = rnd.Next(100000, 999999);

要生成唯一值,您最好的方法是只增加1。产生唯一价值的其他方式在计算上效率越来越低。

此外,您可能希望使用哈希函数,它们提供“几乎”唯一值。但那是我不太熟悉的基础。

第三个选项是使用GUID作为唯一标识符。它们在计算上非常有效,并且即使跨越域边界也保证是独特的。但是,它们大约有80个符号,而不仅仅是6:)

答案 3 :(得分:1)

我在SQL Server 2012中创建了一个简单的订单表,其中包含以下代码,其中ODRID是自定义格式的销售订单ID。

CREATE TABLE [dbo].[OrderTransaction](
[OrderID] [bigint] IDENTITY(1,1) NOT NULL,
[ODRID]  AS (right('ES00000000'+CONVERT([nvarchar](10),[OrderID]),(11))),
[OrganisationID] [bigint] NOT NULL,
[SubTotal] [int] NOT NULL,
[Discount] [int] NOT NULL,
[TotalAmount] [bigint] NOT NULL,
[CreatedBy] [int] NULL,
[CreatedDate] [datetime] NULL,
[ModifieddBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
CONSTRAINT [PK_OrderTransaction] PRIMARY KEY CLUSTERED 
(
[OrderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

答案 4 :(得分:0)

C#

Random rand = new Random();
int randomNumber = rand.Next(100000, 999999);

SQL中有点困难:

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/sql-server-set-based-random-numbers

答案 5 :(得分:0)

您可以使用以下命令从SQL Server获取精确的6位长随机数:

SELECT CAST((RAND() * (899999) + 100000) as int) 

我使用以下代码更新表中具有随机生成数字的字段:

第一部分是每当在表中插入新行时调用的函数。

CREATE VIEW ViewRndNum
AS
SELECT CAST((RAND() * (899999) + 100000) as int);


CREATE FUNCTION [dbo].[GetID](@Counter int = 0)
RETURNS int
AS
BEGIN
    DECLARE @RandNumber as int;
    DECLARE @iEmployeeCode as int;
    DECLARE @iExistingEmployeeCode as int;


    IF (@Counter < 20) 
        BEGIN
        SELECT @iEmployeeCode = RndNum
                    FROM ViewRndNum;


        SELECT @iExistingEmployeeCode = EmployeeCode FROM dbo.Employees WHERE EmployeeCode = @iEmployeeCode
        IF @iExistingEmployeeCode = @iEmployeeCode 
            BEGIN
                SET @Counter = @Counter + 1
                SELECT @iEmployeeCode = [dbo].[GetID](@Counter)
            END
        END
    ELSE
        SET @iEmployeeCode = 99999999
RETURN @iEmployeeCode
END
GO

CREATE TABLE [dbo].[Employees](
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [EmployeeType] [int] NULL,
    [EmployeeID] [bigint] NULL,
    [EmployeeCode] [int] NULL,
    [Employee] [varchar](max) NULL,
    [CreatedDate] [datetime] NULL,
    [LastSeen] [datetime] NULL,
 CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[Employees] ADD  CONSTRAINT [DF_Employees_EmployeeCode]  DEFAULT ([dbo].[getID]((0))) FOR [EmployeeCode]
GO

答案 6 :(得分:0)

function random_numbers($digits,$id) {
$min = pow(10, $digits - 1);
$max = pow(10, $digits) - 1;
$number = mt_rand($min, $max);
$count = strlen($id);
$ssn_id = substr($number, $count);
$ssn_id = trim($id.$ssn_id);
return $ssn_id;
}

echo random_numbers(9,145);

答案 7 :(得分:0)

使用此-

DECLARE @NewPINGenerated Int = CONVERT(numeric(12,0),RAND() * 899999) + 100000
DECLARE @SMS VARCHAR(100)='Message Here '+CAST(@NewPINGenerated as varchar)