0

我想创建一个存储过程,它返回一个介于 (11111,99999) 之间的随机数

前提是该数字不应存在于表中

我使用这个复杂的函数来做到这一点,但我需要将它转换为存储过程

    Function GiveRandomStudentNumber() As String
s:
        Dim rnd As New Random
        Dim st_num As String = rnd.Next(11111, 99999)
        Dim cmd As New SqlCommand("select count(0) from student where st_num = " & st_num,con)
        dd.con.Open()
        Dim count As Integer = cmd.ExecuteScalar()
        dd.con.Close()
        If count <> 0 Then
            GoTo s
        Else
            Return st_num
        End If
    End Function

此功能有效,但我需要将其转换为存储过程..

提前致谢 ...

4

2 回答 2

2
CREATE PROCEDURE [dbo].[Select_RandomNumber] 
(
@Lower INT, --11111-- The lowest random number
@Upper INT --99999-- The highest random number
)
AS
BEGIN

    IF NOT (@Lower < @Upper) RETURN -1

    --TODO: If all the numbers between Lower and Upper are in the table,
    --you should return from here
    --RETURN -2

    DECLARE @Random INT;
    SELECT @Random = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

    WHILE  EXISTS (SELECT * FROM YourTable WHERE randCol = @Random)
    BEGIN

        SELECT @Random = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
    END

    SELECT @Random
END
于 2012-11-26T12:48:58.843 回答
0

创建学生 ID 表。用 X 和 Y 之间的 ID 填充它。每次要使用 ID 时,将其从表中删除。

create table [FreeIDs] (
  [ID] int, 
  [order] uniqueidentifier not null default newid() primary key);
insert into [FreeIDs] ([ID]) values (11111),(11112),...,(99999);

to get a free ID:

    with cte as (
      select top(1) [ID]
      from [FreeIDs] 
      order by [order])
    delete cte
    output deleted.ID;

持久化的预定义器顺序加快了生成新 ID 的速度。

顺便说一句,如果您想“优化”表格并使用数字表格:

with Digits as (
    select Digit 
    from (
        values (0), (1), (2), (3), (4), (5), 
            (6), (7), (8), (9)) as t(Digit)),
Numbers as (
    select u.Digit + t.Digit*10 +h.Digit*100 + m.Digit*1000+tm.Digit*10000 as Number
    from Digits u
    cross join Digits t
    cross join Digits h
    cross join Digits m
    cross join Digits tm)
select top(1) Number 
from Numbers
where Number between 11111 and 99999
and Number not in (
    select ID 
    from Students)
order by (newid());

只是不要。随机化集合的要求是性能杀手,而消除现有(已使用)ID 的连接也是有问题的。但最重要的是,该解决方案在并发下会失败,因为多个请求可以获得相同的 ID(并且随着空闲 ID 数量的减少而增加)。当然,语义上等价的幼稚的逐行缓慢处理,就像您的原始代码或 Kaf 的答案一样,有完全相同的问题,但也很慢。当除了一个 ID 之外的所有 ID 都被拿走时,真的值得测试解决方案,在等待随机数生成器中奖时观察灯光变暗......

于 2012-11-26T12:41:59.053 回答