• Oracle之DBMS_RANDOM包详解


    DBMS_RANDOM是Oracle提供的一个PL/SQL包,用于生成随机数据和字符。它具有以下函数。

    其中,initialize,random,terminate函数在Oracle11g中已不推荐使用,主要用于向后兼容。下面对各个函数进行举例说明

    1. INITIALIZE

    用一个种子值来初始化DBMS_RANDOM包。

    默认情况下,DBMS_RANDOM包是根据用户、时间、会话来进行初始化,这样,即便是同一个语句,每次生成的数值都会不一样,但这样会产生一个问题,在测试环境下,如果我想每次生成的随机序列都是一样的,该怎么办?INITIALIZE函数就很好的解决了这一问题,通过设置相同的种子值,则每次生成的随机序列都将是一样的。

    语法:

    DBMS_RANDOM.INITIALIZE (
             val IN BINARY_INTEGER);

    举例:

    SQL> BEGIN
      2    dbms_random.initialize(100);
      3    FOR i IN 1 .. 10 LOOP
      4       dbms_output.put_line(dbms_random.random); 
      5    END LOOP;
      6  END;
      7  /
    163284779
    751599369
    659804475
    1131809137
    -865013504
    -407075626
    2128226600
    -448154892
    -1371178596
    472933400
    
    PL/SQL procedure successfully completed.

    即便是在不同的会话中,不同的用户下,随机生成的10个值都是一样的。

    2. NORMAL

    NORMAL函数返回服从正态分布的一组数。此正态分布标准偏差为1,期望值为0。这个函数返回的数值中有68%是介于-1与+1之间,95%介于-2与+2之间,99%介于-3与+3之间。

    语法:

    DBMS_RANDOM.NORMAL
            RETURN NUMBER;

    举例:

    SQL> select dbms_random.normal from dual;
    
        NORMAL
    ----------
    .321082788

    3. RANDOM

    RANDOM返回值的范围为: [-2^31, 2^31),返回的是整数。

    语法:

    DBMS_RANDOM.RANDOM
              RETURN binary_integer;

    举例:

    SQL> select dbms_random.random from dual;
    
        RANDOM
    ----------
    -1.363E+09

    4. SEED

    功能和INITIALIZE函数类似,实际上,INITIALIZE函数被淘汰,推荐的替代函数即是SEED函数。与INITIALIZE函数不同的是SEED函数同时支持数值和字符作为种子值,而INITIALIZE函数只支持数值。

    语法:

    DBMS_RANDOM.SEED (
         val IN BINARY_INTEGER);

    DBMS_RANDOM.SEED (
         val IN VARCHAR2);

    举例:

    BEGIN
       dbms_random.seed('hello');
       FOR i IN 1 .. 10 LOOP
          dbms_output.put_line(round(dbms_random.value * 100));
       END LOOP;
    END;

    输出如下:

    58
    71
    33
    4
    39
    53
    93
    37
    20
    5

    其中,VARCHAR2的最大范围为2000.

    5. STRING

    随机生成字符串

    语法:

    DBMS_RANDOM.STRING
          opt IN CHAR,
          len IN NUMBER)
      RETURN VARCHAR2;

    关于opt和len的说明,解释如下:

    可见,opt指的是字符串的格式,len指的是字符串的长度。

    举例:

    SQL> select dbms_random.string('u',10) value from dual;
    
    VALUE
    --------------------
    MCPEZLEQOO
    
    SQL> select dbms_random.string('l',10) value from dual;
    
    VALUE
    --------------------
    laufaqufln
    
    SQL> select dbms_random.string('a',10) value from dual;
    
    VALUE
    --------------------
    vjEetXlItt
    
    SQL> select dbms_random.string('x',10) value from dual;
    
    VALUE
    --------------------
    LAMDGZE22E
    
    SQL> select dbms_random.string('p',10) value from dual;
    
    VALUE
    --------------------
    4LF =Q'(fP

    6. TERMINATE

    在使用完DBMS_RANDOM包后,用该函数进行终止。该函数在11gR1中即不推荐使用了。

    语法:

    DBMS_RANDOM.TERMINATE;

    举例:

    SQL> exec DBMS_RANDOM.TERMINATE;
    
    PL/SQL procedure successfully completed.

    7. VALUE

    语法:

    DBMS_RANDOM.VALUE
       RETURN NUMBER;

    DBMS_RANDOM.VALUE(
           low IN NUMBER,
           high IN NUMBER)
       RETURN NUMBER;

    对于第一种用法,返回的值的范围为大于或等于0,小于1,带有38位精度的小数。

    对于第二种用法,可指定最小值和最大值,返回值的范围为大于或等于low,小于high。

    举例:

    SQL> select dbms_random.value from dual;
    
         VALUE
    ----------
    .291782963
    
    SQL> select dbms_random.value(10,20) from dual;
    
    DBMS_RANDOM.VALUE(10,20)
    ------------------------
              12.4079412

    总结:

    关于VALUE函数返回38位精度的小数,可通过以下方式验证。

    SQL> select dbms_random.value from dual;
    
         VALUE
    ----------
    .511020102
    
    SQL> col value for 999999.9999999999999999999999999999999999999999999999999
    SQL> select dbms_random.value from dual;
    
                                VALUE
    ---------------------------------------------------------
           .1590863051775181450023750363985770254400000000000
    
    SQL> /
    
                                VALUE
    ---------------------------------------------------------
           .5831363280913832608492096535119024112700000000000

    故意将value列的格式设置为999999.9999999999999999999999999999999999999999999999999,当然不限,只要小数位数超过38位即可,在本例中,为49位,通过dbms_random.value随机返回数值,不难发现,最后生成的数值虽然是49位,但最后11位均是0,换句话说,有效数值只有38位。

    参考:

    1. http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_random.htm#ARPLS040

    2. http://zhangzhongjie.iteye.com/blog/1948930

  • 相关阅读:
    【问题备注】VS2012不能输入代码,文字…
    犯错了又
    关于实习…
    百度2014校招笔试题目题解(更新了第1题的算法,10.9下午)
    人人校招笔试题
    腾讯2014软件开发笔试题目
    阿里巴巴笔试题选解
    批处理文件——多个QQ一键登录
    动态规划---LIS
    动态规划--凑硬币问题
  • 原文地址:https://www.cnblogs.com/ivictor/p/4476031.html
Copyright © 2020-2023  润新知