Sql Server可以生成唯一的13位数字

时间:2014-08-25 14:27:45

标签: sql sql-server

我需要生成一个唯一的13位数字。

如果我创建一个以13位数字作为主键的表格,Sql Server能否以某种方式为我生成这个号码?

更新

我希望这个数字看起来像一个随机数,所以不是一个自动递增的数字。

它必须是13位数,它不应该是自动递增的,它应该是唯一的。该数字不应该包含多个零,但它可以包含0-9的数字。

此号码应该看起来像信用卡号码,因此没有尾随零。

5 个答案:

答案 0 :(得分:2)

我的建议是在表格上有一个自动递增的标识列。然后,根据此定义您的值。一个简单的方法是:

create table t (
    tId int identity(1, 1) not null,
    . . .
    myId cast(rand(tId)*10000000000000 as varchar(13))
)

这将其显示为计算列。当然,您可以在创建每一行时分配值。这不能保证产生不同的结果,但是你很可能看到碰撞。

以下是另一种选择也不能保证,但可能有效:

create table t (
    tId varchar(13) default cast(cast(rand(checksum(getdate())*10000000000000 as bigint) as varchar(13)
    . . .
)

编辑:

碰撞的可能性比我预期的要高一点 - 我猜测,我对13位哈希码的直觉是不应该的。

无论如何,有两种冲突来源。第一个是产生相同值的随机数发生器。要处理这个问题,只需假设随机数生成器与checksum()一起实际上是随机的。所以,问题是:两个小于10,000,000,000,000的随机数是相同值的几率是多少?我会让感兴趣的各方在网上搜索一个公式来计算这个。

如果您生成1,000个数字。那么概率基本上是0%,任何两个都是相同的。也就是说,如果您认为它们是不同的,那么前1000个数字是安全的。以下是摘要:

       1,000             0.0000%
      10,000             0.0005%
     100,000             0.0500%
   1,000,000             4.8771%
  10,000,000            99.3262%

高达数十万的价值,你可能非常安全。当你进入数百万 - 甚至是数百万 - 时,碰撞的机会大大增加。

在某些时候,如果你想要很多很多独特的值,你将不得不创建一个包含唯一值的表和一个选择不在表中的值的过程。

正如JohnBarça所指出的:不要在Facebook上使用这种方法制作猫咪照片。

答案 1 :(得分:-1)

只需创建一个Guid(选择newid())&解析它...删除{和' - ' &安培;做一个长度为13的选择。

答案 2 :(得分:-1)

我使用类似的方法在报告系统中生成随机/唯一表名。它可能会为你做的伎俩。只需调整乘数即可影响最终整数长度。

SELECT CONVERT(BIGINT,RAND()*10000000000000)

作为一张桌子......

CREATE TABLE #test (testID INT,
                    UniqueID AS CONVERT(BIGINT,RAND()*10000000000000))

INSERT INTO #test (testID)
SELECT 1

SELECT * FROM #TEST

DROP TABLE #test

只需在testID中插入一个值(每次可以为1),就会生成一个新的UniqueID。您应该在任何生产表上都有一个主键。

注意:虽然重复发生的可能性非常小,但仍可能发生。

答案 3 :(得分:-1)

SELECT CEILING(RAND()*9999999999999)

答案 4 :(得分:-2)

这样的事情可能有用:

use [chamomile]; 
go 
if object_id(N'[utility].[table_01]', N'U') is not null 
  drop table [utility].[table_01]; 
go 
if object_id(N'[utility].[generate_random_sequence]', N'FN') is not null 
  drop function [utility].[generate_random_sequence]; 
go 
/* 
  select [utility].[generate_random_sequence] (rand()); 
*/ 
create function [utility].[generate_random_sequence] ( 
  @random [float]) 
returns [bigint] 
as 
  begin 
      declare @return [bigint] = ceiling(@random * 9999999999999); 
      while @return > 9999999999999 
             or @return < 1000000000000 
        set @return = ceiling(@random * 9999999999999); 
      return @return; 
  end; 
go 
if object_id(N'[utility].[table_01]', N'U') is not null 
  drop table [utility].[table_01]; 
go 
create table [utility].[table_01] ( 
  [my_id] as [utility].[generate_random_sequence] (rand()) 
  , [flower] [sysname] 
  ); 
go 
insert into [utility].[table_01] 
            ([flower]) 
values      (N'rose'); 
select * 
from   [utility].[table_01];