2016-11-12 3 views
0

xからyまでの範囲でn個の固有番号を生成するプロシージャを記述する必要がありますか?重複は許可されません。 dbms_random.value(x、y)で乱数を生成できますが、値は繰り返されます。複写せずにpl/sqlで乱数を生成しますか?

+0

nに上限を指定する必要があります。 nが大きすぎる場合、問題は解決されない可能性があります(マシンで表現できる数値の数は常に有限ですので、nがその数より大きい場合は解はありません)。 nがまだ非常に大きいが、第1の意味では「大きすぎる」ものではない場合、問題は解決可能であるが、9,000年の推定時間である。それでは、なぜPROCEDUREを書く必要がありますか?これはプレーンなSQLで行うことができます。 "手続き"は文字通り意味しますか?これはPL/SQLのクラス、または手続きですか?または、十分なプレーンなSQLソリューションですか? – mathguy

答えて

3

最初にオフにしてください - 数字が重複なしで生成されなければならない場合、本当にランダムではありません。

これはクラス割り当てのように聞こえるので、私はコードを書くつもりはありません。ただし、次のような方法があります。

UNIQUE_NUMBERSという名前のUNIQUE_NUMBERという名前の1つのNUMBER型列を作成します。この列は一意に制約されています。あなたの関数では、数値を生成してからUNIQUE_NUMBERSに挿入します。それが正しく挿入されていれば、値は一意であり、関数は挿入をCOMMITしてその値を返すことができます。例外がある場合は、値が既に存在することを意味し、挿入されず、ループバックして別の番号をランダムに生成する必要があります。

幸運のベスト。

+0

Upvote、特にteh codezを与えるだけではない。 –

1

CTEを使用して、xからyまでの数値を生成できます。そして、あなたはランダムに並べ替えることができます。

with n as (
     select level as n 
     from dual 
     connect by level <= ("x" - "y" + 1) 
    ), 
    rand_n as (
     select n + "x" - 1 
     from n 
     order by dbms_random.random 
    ) 
select * 
from rand_n; 

これは、もちろん、「x」と「y」との違いは本当に巨大ではないことを前提としています。

+0

??あなたは外側のクエリで、おそらく 'rownum <= n'のような制限フィルタを持つことを意味しましたか?書かれたクエリは 'x'と' y'の間のすべての数値を返します。 (また、OPが変数 'n'を持つのに役立つわけではなく、あなたはテーブルと列' n'の名前を選んだのです)。 – mathguy

1

1つの方法は、nより多くの数値を生成することです(たとえば、10%増)。 nの数字が1.1 * n番以内にある確率はおそらく非常に低く、そのような状況になるまでの予想時間は太陽系の寿命よりも長い(nがかなり小さい場合)。

次に、少なくともnが区別されることを完全に期待する1.1 * nの乱数を使用すると、別のを選択してrownumでフィルタリングすることができます。

関連する問題