Rem
Rem $Header: dbmsrand.sql 14-apr-97.15:57:11 rwessman Exp $
Rem
Rem dbmsrand.sql
Rem
Rem  Copyright (c) Oracle Corporation 1997. All Rights Reserved.
Rem
Rem    NAME
Rem      dbmsrand.sql - <one-line expansion of the name>
Rem
Rem    DESCRIPTION
Rem      <short description of component this file declares/defines>
Rem
Rem    NOTES
Rem      <other useful comments, qualifications, etc.>
Rem
Rem    MODIFIED   (MM/DD/YY)
Rem    rwessman    04/14/97 - Renamed package to conform to naming standards.
Rem    rwessman    04/14/97 - PL/SQL random number package
Rem    rwessman    04/14/97 - Renamed from network_src/admin/random.sql.
Rem
CREATE OR REPLACE PACKAGE dbms_random AS

    ------------
    --  OVERVIEW
    --
    --  This package provides a built-in random number generator. It is
    --  faster than generators written in PL/SQL because it calls Oracle's
    --  internal random number generator.
    --------
    --  USAGE
    --
    --  The package must be initialized prior to calling the random number
    --  generator. If the initialization routine is not called, the package
    --  will raise an exception.
    --  The generator produces 8 digit integers.
    --  This is a simple interface. For more options, the cryptographic toolkit
    --  interface should be used.
    --------
    --  EXAMPLES
    --
    --  To use the package, first call the initialize routine with the seed to
    --  use. Use a seed that is sufficiently large, more than 5 digits. A
    --  single digit will likely not return sufficiently random numbers.
    --  For example:
    --      Initialize(59860342);
    --  To get the random number, simply call the function, e.g.
    --      my_random_number := Random;
    --  To reset the seed, call the seed procedure as in:
    --      Seed(30896547);
    --  When finished with the package, call the Terminate procedure.

    PROCEDURE Initialize(seed IN BINARY_INTEGER);

    PROCEDURE Seed(seed IN BINARY_INTEGER);

    FUNCTION Random RETURN BINARY_INTEGER;

    PROCEDURE Terminate;

END dbms_random;
/
CREATE OR REPLACE PACKAGE BODY dbms_random AS

    initialized BOOLEAN := FALSE;
    package_not_initialized EXCEPTION;

    -- Dummy persona needed to satisfy the Cryptographic toolkit package. It is
    -- not (yet) used by the random number functions.
    persona dbms_crypto_toolkit.Persona := NULL;

    PROCEDURE CheckInitialized IS
    BEGIN
        IF initialized = FALSE THEN
            RAISE package_not_initialized;
        END IF;
    END CheckInitialized;

    PROCEDURE Initialize(seed IN BINARY_INTEGER) IS
    BEGIN
        dbms_crypto_toolkit.Initialize;
        dbms_crypto_toolkit.SeedRandom(persona, seed);
        initialized := TRUE;
    END Initialize;

    PROCEDURE Seed(seed IN BINARY_INTEGER) IS
    BEGIN
        CheckInitialized;
        dbms_crypto_toolkit.SeedRandom(persona, seed);
    END Seed;

    FUNCTION Random RETURN BINARY_INTEGER IS
        random_number BINARY_INTEGER;
    BEGIN
        CheckInitialized;
        dbms_crypto_toolkit.RandomNumber(persona, random_number);
        RETURN random_number;
    END Random;

    PROCEDURE Terminate IS
    BEGIN
        IF initialized THEN
            dbms_crypto_toolkit.Terminate;
        END IF;
    END Terminate;

END dbms_random;
/
DROP PUBLIC SYNONYM dbms_random;
/
CREATE PUBLIC SYNONYM dbms_random FOR sys.dbms_random;
/
GRANT EXECUTE ON dbms_random TO public;
/

