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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM