1 取随机数
Oralce把所有有关随机数的操作都封装在了PL/SQL包DBMS_RANDOM里,极大地方便了我们的使用。它具有以下函数:
其中,initialize,random,terminate函数在Oracle11g中已不推荐使用,主要用于向后兼容。下面对各个函数进行举例说明。
1.1 INITIALIZE
用一个种子值来初始化DBMS_RANDOM包。
默认情况下,DBMS_RANDOM包是根据用户、时间、会话来进行初始化,这样,即便是同一个语句,每次生成的数值都会不一样,但这样会产生一个问题,在测试环境下,如果我想每次生成的随机序列都是一样的,该怎么办?INITIALIZE过程就很好的解决了这一问题,通过设置相同的种子值,则每次生成的随机序列都将是一样的。
语法:
DBMS_RANDOM.INITIALIZE (val IN BINARY_INTEGER);
举例:
BEGIN DBMS_RANDOM.INITIALIZE(100); FOR I IN 1 .. 10 LOOP DBMS_OUTPUT.PUT_LINE(DBMS_RANDOM.RANDOM); END LOOP; END;
--------------------------
163284779
751599369
659804475
1131809137
-865013504
-407075626
2128226600
-448154892
-1371178596
472933400
即便是在不同的会话中,不同的用户下,随机生成的10个值都是一样的。
1.2 NORMAL
NORMAL函数返回服从正态分布的一组数。此正态分布标准偏差为1,期望值为0。这个函数返回的数值中有68%是介于-1与+1之间,95%介于-2与+2之间,99%介于-3与+3之间。
语法:
DBMS_RANDOM.NORMAL RETURN NUMBER;
举例:
SELECT DBMS_RANDOM.NORMAL FROM DUAL;
--------------
0.321082787751054
1.3 RANDOM
返回值的范围为: [-2^31, 2^31),返回的是整数。
语法:
DBMS_RANDOM.RANDOM RETURN binary_integer;
举例:
SELECT DBMS_RANDOM.RANDOM FROM DUAL;
-------------
1632572475
SELECT ABS(MOD(DBMS_RANDOM.RANDOM,100)) FROM DUAL;--获取0-100内的随机整数
--------------
51
1.4 SEED
功能和INITIALIZE过程类似,实际上,INITIALIZE过程被淘汰,推荐的替代过程即是SEED存储过程,与INITIALIZE过程不同的是SEED过程同时支持数值和字符作为种子值,而INITIALIZE过程只支持数值。
语法:
DBMS_RANDOM.SEED (val IN BINARY_INTEGER); DBMS_RANDOM.SEED (val IN VARCHAR2);--VARCHAR2的最大范围为2000
举例:
BEGIN DBMS_RANDOM.SEED('hello'); FOR I IN 1 .. 10 LOOP DBMS_OUTPUT.PUT_LINE(DBMS_RANDOM.VALUE); END LOOP; END;
-------------------
58
71
33
4
39
53
93
37
20
5
5. STRING
随机生成字符串,语法:
DBMS_RANDOM.STRING( opt IN CHAR,--字符串的格式 len IN NUMBER--字符串的长度 ) RETURN VARCHAR2;
--opt 字符串的格式:
– 'u'或'U':大写字母的字符串
– 'l'或'L':小写字母的字符串
– 'a'或'A':不区分大小写的任意字符串
– 'x'或'X':任意大小写字母或数字的字符串
– 'p'或'P':任意可输出字符的数组
举例:
SELECT DBMS_RANDOM.STRING('u', 10) VALUE FROM DUAL; -------------------- PSXFAKZZTR SELECT DBMS_RANDOM.STRING('l', 10) VALUE FROM DUAL; -------------------- elnircffly SELECT DBMS_RANDOM.STRING('a', 10) VALUE FROM DUAL; ------------------- vGuYnPoZNk SELECT DBMS_RANDOM.STRING('x', 10) VALUE FROM DUAL; -------------------- LH7Q36NLPR SELECT DBMS_RANDOM.STRING('p', 10) VALUE FROM DUAL; -------------------- IuX4B8lQ9p
6. TERMINATE
在使用完DBMS_RANDOM包后,用该过程进行终止。该过程在11gR1中即不推荐使用了。
语法:
DBMS_RANDOM.TERMINATE;--For compatibility with 8.1
7. VALUE
此函数最为常用,其语法为:
DBMS_RANDOM.VALUE RETURN NUMBER;--[0,1),带有38位精度的小数 DBMS_RANDOM.VALUE( low IN NUMBER,--最小值 high IN NUMBER--最大值 ) RETURN NUMBER;
举例:
SELECT DBMS_RANDOM.VALUE FROM DUAL; ---------------------- 0.452943599091639 SELECT DBMS_RANDOM.VALUE(10, 20) FROM DUAL; ------------------------ 18.4659055244849
2 随机取数据
Oracle随机取数据的方法,一般有以下两种:
2.1 快速随机取数据
使用oracle的sample([sample_percent])或sample bloc(sample_percent)方法(采样表扫描(sample table scan)),快速随机取数据,推荐使用:
SELECT * FROM EBILL_ELECTRONIC_BILL SAMPLE(1) WHERE ROWNUM <= 10; --参数表示取样百分比,缺省时,取头10条
类似的还有,sample_block:
SELECT * FROM EBILL_ELECTRONIC_BILL SAMPLE BLOCK(1) WHERE ROWNUM <= 10; --参数表数据存储区间取样百分比,必填
主要注意以下几点:
1.sample_percent是一个数字,定义结果集中包含记录占总记录数量的百分比,值应该在[0.000001,99.999999]之间。
2.sample只对单表生效,不能用于表连接和远程表
3.sample会使SQL自动使用CBO(基于代价的优化器)
2.2 随机取数据
使用dbms_random.value随机取数据,会全表扫描(Full table Scan),比较慢,不推荐使用:
SELECT * FROM (SELECT * FROM EBILL_ELECTRONIC_BILL ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <= 10