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 の回答のように、意味的に同等の単純な行ごとの非常に遅い行処理には、まったく同じ問題がありますが、単純に遅いだけです。1 つを除くすべての ID が取得されたときにソリューションをテストすることは、本当に価値があります。

于 2012-11-26T12:41:59.053 に答える