DBMS_RANDOM 生成随机数值或字符串

Oracle DBMS_RANDOM 包是一个可以生成随机数值或者字符串的程序包,该包有 initialize()、seed()、terminate()、value()、normal()、random()、string() 等几个函数。

DBMS_RANDOM.value()

value() 函数是最常用的,该函数有两个种用法:

第一种用法:这种用法没有参数,会返回一个具有 38 位精度的数值,范围从 0.0 到 1.0,但不包括 1.0。如下:

SQL> set serverout on
SQL> begin
  2  for i in 1..10 loop
  3  dbms_output.put_line(round(dbms_random.value*100));
  4  end loop;
  5  end;
  6  /
60
86
3
4
45
25
50
54
35
42

PL/SQL 过程已成功完成。

第二种用法:value() 函数带有两个参数,第一个指下限,第二个指上限,将会生成下限到上限之间的数字,但不包含上限。如下:

SQL> set serverout on
SQL> begin
  2  for i in 1..10 loop
  3  dbms_output.put_line(trunc(dbms_random.value(1,101)));
  4  end loop;
  5  end;
  6  /
24
94
10
67
88
75
81
36
69
73

PL/SQL 过程已成功完成。

DBMS_RANDOM.string(arg1, arg2) 

某些用户管理程序可能需要为用户创建随机的密码。使用 Oracle 10G 下的 DBMS_RANDOM.string() 方法可以实现这样的功能。

DBMS_RANDOM.string() 参数说明:

  • arg1 参数的取值如下:

    • 'u', 'U' - 以大写字母字符返回字符串

    • 'l', 'L' - 返回小写字母字符的字符串

    • 'a', 'A' - 返回混合大小写字母字符的字符串

    • 'x', 'X' - 返回大写字母数字字符的字符串

    • 'p', 'P' - 返回任何可打印字符的字符串。否则返回的字符串是大写字母字符。

  • arg2 表示返回的字符串长度

示例如下:

SQL> select dbms_random.string('P',8 ) from dual ;

DBMS_RANDOM.STRING('P',8)
--------------------------------------------------------------------------------
@1GR/sdp


SQL> select dbms_random.string('U', 8) from dual ;

DBMS_RANDOM.STRING('U',8)
--------------------------------------------------------------------------------
TFMAIOUF


SQL> select dbms_random.string('X', 8) from dual ;

DBMS_RANDOM.STRING('X',8)
--------------------------------------------------------------------------------
GQYMD0A6


SQL> select dbms_random.string('A', 8) from dual ;

DBMS_RANDOM.STRING('A',8)
--------------------------------------------------------------------------------
MJGuidWn


SQL> select dbms_random.string('x', 8) from dual ;

DBMS_RANDOM.STRING('X',8)
--------------------------------------------------------------------------------
14ZRQQW6

DBMS_RANDOM.random()

random() 方法返回的是 BINARY_INTEGER 类型值,产生一个任意大小的随机数。与 DBMS_RANDOM.value 的区别举例:

Order By DBMS_RANDOM.value;

这条语句功能是实现记录的随机排序。另外:

DBMS_RANDOM.value 和 DBMS_RANDOM.random 两者之间有什么区别?

(1)Order By DBMS_RANDOM.value 为结果集的每一行计算一个随机数,DBMS_RANDOM.value 是结果集的一个列(虽然这个列并不在 select 列表中),然后根据该列排序,得到的顺序自然就是随机的。

(2)看看 desc 信息便知道 value 和 random 这两个函数的区别了,value 返回的是 number 类型,并且返回的值介于 1 和 0 之间,而 random 返回的是 BINARY_INTEGER 类型。

示例如下:

SQL> select dbms_random.random() from dual;

DBMS_RANDOM.RANDOM()
--------------------
          -101615598


SQL> select dbms_random.random() from dual;

DBMS_RANDOM.RANDOM()
--------------------
          2138814345

DBMS_RANDOM.normal()

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

示例用法:

SQL> select dbms_random.normal() from dual;

DBMS_RANDOM.NORMAL()
--------------------
           1.8796059


SQL> select dbms_random.normal() from dual;

DBMS_RANDOM.NORMAL()
--------------------
          -1.1685486

DBMS_RANDOM.seed()

seed() 用于生成一个随机数种子,设置种子的目的是可以重复生成随机数,用于调试。否则每次不同,难以调度。

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

示例如下:

SQL> set serveroutput on
SQL> begin
  2  dbms_random.seed('a');
  3  for i in 1 .. 10 loop
  4  dbms_output.put_line(round(dbms_random.value * 100));
  5  end loop;
  6  end;
  7  /
4
68
86
80
34
75
56
3
71
42

PL/SQL 过程已成功完成。

DBMS_RANDOM.initialize(val IN BINARY_INTEGER)

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

示例如下:

SQL> set serveroutput on
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 过程已成功完成。

上面SQL片段执行多次,你会发现输出的随机序列是一致的。

DBMS_RANDOM.terminate()

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

示例如下:

SQL> exec DBMS_RANDOM.terminate;

PL/SQL 过程已成功完成。

关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号