DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Генерирование отрицательных чисел

До сих пор мы рассматривали только генерирование положительных чисел и не касались отрицательных. Но предположим, что наше банковское приложение позволяет работать с перерасходом средств, то есть с временным заимствованием денег со счетов. В таком случае ос-
таток на счете может стать отрицательным (состояние, известное как «овердрафт»). В тестовых данных могут понадобиться и такие счета. Функция DBMS_RANDOM.RANDOM позволяет сделать это в PL/SQL.
Функция RANDOM
В пакете DBMS_RANDOM имеется функция RANDOM для генерации случайных целых чисел, вызываемая без параметров и возвращающая двоичное целое в диапазоне от -231 до 231, то есть целое десятизначное десятичное число. Используется она просто:

Обратите внимание, что в данном конкретном примере присутствуют одновременно отрицательные и положительные целые числа длиной до 10 разрядов. Нет никакой гарантии, что при вызове этой программы вы получите отрицательное случайное число. Если необходимо, чтобы получаемое отрицательное случайное число соответствовало определенному формату, используйте комбинацию функций RANDOM и VALUE, как показано ниже.
Функцию get_num можно изменить так, чтобы она принимала параметр, позволяющий ей генерировать отрицательные числа.


Здесь сохранена функциональность исходной версии функции get_num (принимающей параметры диапазона high и low и параметр точности scale) и добавлена новая возможность, позволяющая генерировать как положительные, так и отрицательные случайные числа.
Задание начального значения для генератора случайных чисел
Что делает случайные числа действительно случайными? Чтобы вы поняли, о чем идет речь, вот вам упражнение: быстро придумайте число, любое число. Какое число пришло вам на ум? Наверняка оно что-нибудь значит для вас: ваш возраст, часть вашего телефонного номера или номер дома - что-то, что вам знакомо или находится в поле зрения в данный момент. Другими словами, выбор этого числа не был случайным, а, следовательно, может быть повторен или предсказан.
Хорошо, скажете вы. Вам нужно случайное число? Я закрою глаза и буду беспорядочно давить на клавиши калькулятора. Нет сомнений, что такое число будет случайным.
Скорее всего, нет. Если вы внимательно посмотрите на такое число, то заметите, что некоторые цифры образуют повторяющиеся последовательности. Это естественно: если вы нажали клавишу (например, 9), то высока вероятность того, что вы нажмете ее еще раз, так как ваш палец завис в непосредственной близости от нее.
Надеюсь, после этих мысленных экспериментов вы понимаете, что человеку достаточно трудно придумать действительно случайное число. Так же и машина не может просто взять число «из ниоткуда». Есть ряд математических методов, обеспечивающих истинную случайность, но их рассмотрение не входит в задачи этой книги. Во всех генераторах случайных чисел есть общий, повсеместно доступный источник «случайностей», такой как системный таймер, который гарантирует, что значения, взятые в любые два момента времени, будут различны. Этот случайный компонент, концептуально аналогичный области перемещения вашего пальца над клавиатурой калькулятора при наборе случайного числа, называется начальным значением последовательности случайных чисел (seed). Если такое начальное значение выбрано достаточно случайно, то и генерируемое число действительно будет случайным. Если начальное значение не меняется, генерируемое чис ло может не быть в полной мере случайным. Образец может повториться и быть легко угадан. Следовательно, выбор начального значения последовательности очень важен при генерировании случайных чисел.
Пакет DBMS_RANDOM включает в себя процедуру INITIALIZE, которая предоставляет начальное значение последовательности случайных чисел, используемое затем в функции-генераторе случайных чисел. Вот пример вызова этой программы:

Процедура принимает аргумент типа BINARY_INTEGER и использует его в качестве начального значения последовательности случайных чисел. Чем длиннее такое начальное значение, тем более случайным будет генерируемое число. Как правило, значения, содержащие более 5 знаков, обеспечивают приемлемую степень случайности.
Совершенно не обязательно явно вызывать процедуру INITIALIZE; при использовании пакета DBMS_RANDOM это вообще не требуется. По умолчанию, если не было явной инициализации, Oracle выполняет автоматическую инициализацию значениями даты и идентификаторов пользователя и процесса.
Итак, для достижения истинной случайности, значение не должно быть постоянным. Хорошим источником данных для получения начального значения последовательности случайных чисел является системное время, которое гарантированно принимает различные значения на протяжении 24-часового периода, например:

Здесь в качестве начального значения использованы месяц, день, час, минуты и секунды. Это значение используется при первой генерации случайного числа, однако, если использовать это же значение на протяжении всего сеанса, случайность может быть нарушена. Следовательно, необходимо периодически задавать новое начальное значение. Для этого существует процедура SEED, которая, как и INITIALIZE, принимает параметр типа BINARY_INTEGER.

Когда генерирование начальных значений в рамках сеанса больше не требуется, можно вызвать процедуру TERMINATE, как показано ниже, чтобы прекратить создание новых значений (и перестать расходовать на это циклы ЦПУ).
 









jAntivirus