DBMS_RANDOM 提供四種核心函數:NORMAL (常態分佈)、RANDOM (整數範圍)、VALUE (浮點區間)、STRING (隨機字串)。本文詳細說明各函數語法、回傳範圍、統計特性與實戰應用場景。
-- 無參數,回傳 NUMBER,平均 0,標準差 1
-- 理論範圍 (-∞, +∞),實務 99.7% 落在 [-3, 3]
SELECT DBMS_RANDOM.NORMAL FROM DUAL;
-- 實測 100,000 次最大值約 5.15
DECLARE
V_MAX NUMBER := 0;
BEGIN
FOR I IN 1..100000 LOOP
V_MAX := GREATEST(V_MAX, DBMS_RANDOM.NORMAL);
END LOOP;
DBMS_OUTPUT.PUT_LINE('MAX: ' || V_MAX);
END;
/
應用:蒙地卡羅模擬、統計抽樣、生成測試資料符合常態分佈
-- 無參數,回傳 -2^31 ~ 2^31-1 之間的整數
SELECT DBMS_RANDOM.RANDOM FROM DUAL;
-- 範圍:-2147483648 ~ 2147483647
應用:需要大範圍整數隨機種子、雜湊鹽值
| 語法 | 回傳範圍 | 精度 |
|---|---|---|
DBMS_RANDOM.VALUE | 0 ~ 1 (不含 1) | 38 位小數 |
DBMS_RANDOM.VALUE(low, high) | low ~ high (不含 high) | 38 位小數 |
-- 基礎用法
SELECT DBMS_RANDOM.VALUE FROM DUAL; -- 0.58983014999643548701631750396301271752
SELECT DBMS_RANDOM.VALUE(100, 500) FROM DUAL; -- 412.150194612502916808701157054098274240
-- 實戰:生成隨機價格 (2 位小數)
SELECT ROUND(DBMS_RANDOM.VALUE(10, 1000), 2) AS PRICE FROM DUAL;
-- 實戰:隨機排序
SELECT * FROM EMP ORDER BY DBMS_RANDOM.VALUE;
DBMS_RANDOM.STRING(opt, len)
-- opt: 'U'/'u' 大寫字母 | 'L'/'l' 小寫字母 | 'A'/'a' 大小寫混合 | 'X'/'x' 大寫字母數字 | 'P'/'p' 可列印字元
-- len: 長度 (最大 60)
| 選項 | 字元集 | 範例 |
|---|---|---|
| U | A-Z | KJHFD |
| L | a-z | kjhfd |
| A | a-z, A-Z | KjHfD |
| X | A-Z, 0-9 | K3J9F |
| P | 可列印 ASCII (含符號) | K#j$F |
-- 生成 30 碼大寫隨機字串
SELECT DBMS_RANDOM.STRING('U', 30) FROM DUAL;
-- 實戰:生成臨時密碼 (8-12 碼,含字母數字)
SELECT DBMS_RANDOM.STRING('X', TRUNC(DBMS_RANDOM.VALUE(8, 13))) AS TEMP_PWD FROM DUAL;
-- 實戰:生成驗證碼 (6 碼數字)
SELECT TRUNC(DBMS_RANDOM.VALUE(100000, 1000000)) AS VERIFY_CODE FROM DUAL;
-- 設定種子 (Session 級)
EXEC DBMS_RANDOM.SEED(12345);
-- 或
EXEC DBMS_RANDOM.SEED('MY_SEED_STRING');
-- 之後的呼叫序列固定
SELECT DBMS_RANDOM.VALUE FROM DUAL; -- 永遠回傳相同值
SELECT DBMS_RANDOM.VALUE FROM DUAL; -- 固定序列第 2 個值
-- 重置為系統時間種子
EXEC DBMS_RANDOM.SEED;
應用:測試案例固定隨機資料、Debug 重現問題
DBMS_RANDOM 需初始化 DBMS_RANDOM.INITIALIZE,10g+ 自動初始化DBMS_RANDOM 為 PL/SQL 呼叫有 Context Switch 開銷,考慮用 CONNECT BY LEVEL + DBMS_RANDOM.VALUE 單一 SQL 生成DBMS_CRYPTO.RANDOMBYTES 或 SYS_GUID()