воскресенье, 21 марта 2010 г.

Генерация случайных чисел в заданном диапазоне

На практике часто требуется генерировать случайные числа в заданном диапазоне. Рассмотрим наиболее естественный способ сделать это на PL/SQL.


Для генерации случайных чисел на PL/SQL существует замечательный пакет dbms_random. Этот пакет содержит все необходимые нам функции.

Прежде всего любой генератор случайных чисел на люьом языке программирования необходимо инициализировать некоторым случайным числом. Это необходимо для того, чтобы не получить в следующей сессии точно такой же набор «случайных» чисел. Инициализация генератора выполняется при помощи функции dbms_random.initialize(n), где n – некоторое случайное число, seed, характеризующее распределение случайных чисел, которые будут получаться в дальнейшем по сле инициализации. В PL/SQL достаточно написать, например, так:
dbms_random.initialize(100);
для инициализации в сессии sql plus необходимо написать так:
exec dbms_random.initialize(100);

Заметим, что значение для инициализации генератора случайных чисел должно быть достаточно большим, от шести до десяти цифр. Малое значение seed может не обеспечить генерацию достаточно случайных чисел.

Вопрос состоит в том, где взять достаточно случайное число для инициализации нашего генератора. Логично использовать текущее время в представлении gv$timer. Например, используя такой запрос:
select hsecs into n from gv$timer;
где n – заранее объявленная переменная в нашей PL/SQL функции, в которой требуется генерация случайных чисел.

Теперь мы можем получить наше случайное число, используя функцию dbms_random.value(min_val,max_val), где min_val – минимальная граница диапазона, max_val – максимальная граница диапазона.

После генерации требуемого количества случайных чисел желательно выполнить команду прекращения использования инициализированной сессии генерации случайных чисел при помощи команды
dbms_random.terminate;

Источник.

UPD1:
Напишем небольшую процедуру для закрепления знаний. По заданию нужно вывести десять случайных 4-хзначных числа:
declare
  n number;
begin
  select hsecs into n from gv$timer;
  dbms_random.initialize(n);
  for i in 1 .. 10 loop
    dbms_output.put_line(round(dbms_random.value(1000, 9999)));
  end loop;
  dbms_random.terminate;
end;
Результат:
SQL> declare
  2    n number;
  3  begin
  4    select hsecs into n from gv$timer;
  5    dbms_random.initialize(n);
  6    for i in 1 .. 10 loop
  7      dbms_output.put_line(round(dbms_random.value(1000, 9999)));
  8    end loop;
  9  end;
 10  /
 
9001
1437
9709
7417
3950
4019
6056
6304
4385
7072
 
PL/SQL procedure successfully completed

1 комментарий: