Oracle生成隨機(jī)數(shù)字、字符串、日期、驗(yàn)證碼及 UUID的方法
在日常生活中,隨機(jī)數(shù)對(duì)于我們而言并不陌生,例如手機(jī)短信驗(yàn)證碼就是一個(gè)隨機(jī)的數(shù)字字符串;對(duì)于統(tǒng)計(jì)分析、機(jī)器學(xué)習(xí)等領(lǐng)域而言,通常也需要生成大量的隨機(jī)數(shù)據(jù)用于測(cè)試、數(shù)據(jù)抽樣、算法驗(yàn)證等。那么今天我們就來(lái)談?wù)勅绾卧?Oracle 數(shù)據(jù)庫(kù)中生成隨機(jī)數(shù)據(jù)。
📝計(jì)算機(jī)生成的都是偽隨機(jī)數(shù),并不是真正的物理隨機(jī)數(shù)。
生成隨機(jī)數(shù)字
Oracle 提供了一個(gè)系統(tǒng)程序包 DBMS_RANDOM,可以用于生成隨機(jī)數(shù)據(jù),例如隨機(jī)數(shù)字、隨機(jī)字符串等。
生成 0 到 1 之間的隨機(jī)數(shù)
DBMS_RANDOM.VALUE 函數(shù)可以用于生成一個(gè)大于等于 0 小于 1 的隨機(jī)數(shù)字。例如:
SELECT dbms_random.value FROM dual; VALUE | ----------------------------------------| 0.82366672879802619203358096665727275462| SELECT dbms_random.value FROM dual; VALUE | ----------------------------------------| 0.47093028485681981896753470853250955607|
DBMS_RANDOM.VALUE 函數(shù)返回的數(shù)據(jù)包含 38 位小數(shù),每次返回不同的數(shù)據(jù)。
有時(shí)候,例如測(cè)試時(shí),我們想要確保每次運(yùn)行時(shí)生成相同的隨機(jī)數(shù)。這種情況下,我們可以使用存儲(chǔ)過(guò)程 DBMS_RANDOM.SEED 設(shè)置一個(gè)隨機(jī)數(shù)種子,然后再創(chuàng)建隨機(jī)數(shù)就可以返回固定的數(shù)值。例如:
CALL dbms_random.seed(1); SELECT dbms_random.value FROM dual; VALUE | ----------------------------------------| 0.75096444209816859425547820733985992585| CALL dbms_random.seed(1); SELECT dbms_random.value FROM dual; VALUE | ----------------------------------------| 0.75096444209816859425547820733985992585|
從結(jié)果可以看出,相同的種子返回了相同的隨機(jī)數(shù)。每次運(yùn)行隨機(jī)數(shù)函數(shù)之前,都需要執(zhí)行一次 DBMS_RANDOM.SEED 過(guò)程。
📝除了整數(shù)類型的種子數(shù)之外,也可以使用字符串作為隨機(jī)數(shù)的種子。
生成指定范圍內(nèi)的隨機(jī)數(shù)
DBMS_RANDOM.VALUE 函數(shù)也可以接收兩個(gè)輸入?yún)?shù):
DBMS_RANDOM.VALUE( low IN NUMBER, high IN NUMBER) RETURN NUMBER;
這種形式的函數(shù)將會(huì)返回一個(gè)大于等于 low,小于 high 的隨機(jī)數(shù)。例如:
CALL dbms_random.seed(1); SELECT dbms_random.value(10, 20) FROM dual; DBMS_RANDOM.VALUE(10,20) | ----------------------------------------| 17.5096444209816859425547820733985992585|
以上示例返回了一個(gè)大于等于 10,小于 20 的數(shù)字。
如果想要生成某個(gè)范圍內(nèi)的隨機(jī)整數(shù),可以利用 DBMS_RANDOM.VALUE 加上 TRUNC 函數(shù)實(shí)現(xiàn)。例如:
CALL dbms_random.seed(1); SELECT trunc(dbms_random.value(10, 20)) v FROM dual; V | --| 17|
注意,以上語(yǔ)句返回的是大于等于 10,小于等于 19(不是 20)的整數(shù)。
生成 6 位數(shù)字手機(jī)驗(yàn)證碼
以下語(yǔ)句可以用于生成一個(gè)由 6 位數(shù)字字符組成的驗(yàn)證碼:
CALL dbms_random.seed(0); SELECT lpad(trunc(dbms_random.value(0, 1000000)),6,'0') captcha FROM dual; CAPTCHA| -------| 063365 |
lpad 函數(shù)可以確保數(shù)據(jù)不夠 6 位時(shí)在前面補(bǔ)足 0。
生成標(biāo)準(zhǔn)正態(tài)分布隨機(jī)數(shù)
DBMS_RANDOM.VALUE 函數(shù)生成的是一個(gè)均勻分布的隨機(jī)數(shù),而 DBMS_RANDOM.NORMAL 函數(shù)可以用于返回一個(gè)遵循標(biāo)準(zhǔn)正態(tài)分布(期望值為 0,標(biāo)準(zhǔn)差為 1)的隨機(jī)數(shù)。例如:
CALL dbms_random.seed(1); SELECT dbms_random.normal FROM dual; NORMAL | ------------------------------------------| 0.4116858715102697161411270380245532257962|
生成隨機(jī)字符串
生成固定長(zhǎng)度的隨機(jī)字符串
除了隨機(jī)數(shù)字之外,DBMS_RANDOM.STRING 函數(shù)可以用于產(chǎn)生一個(gè)隨機(jī)字符串:
DBMS_RANDOM.STRING opt IN CHAR, len IN NUMBER) RETURN VARCHAR2;
其中,參數(shù) opt 可以指定返回字符串的類型:
- ‘u', ‘U',返回由大寫(xiě)字母組成的字符串;
- ‘l', ‘L',返回由小寫(xiě)字母組成的字符串;
- ‘a(chǎn)', ‘A',返回由大小寫(xiě)混合字母組成的字符串;
- ‘x', ‘X',返回由大寫(xiě)字母和數(shù)字組成的字符串;
- ‘p', ‘P',返回由任意可打印字符組成的字符串;
- 其他參數(shù),返回由大寫(xiě)字母組成的字符串。
參數(shù) len 表示返回字符串的長(zhǎng)度。例如:
CALL dbms_random.seed(1); SELECT dbms_random.string('p', 10) FROM dual; DBMS_RANDOM.STRING('P',10)| --------------------------| gqB!U5t^a6 |
以上示例返回了一個(gè)長(zhǎng)度為 10,由任意可打印字符組成的隨機(jī)字符串。
生成可變長(zhǎng)度的隨機(jī)字符串
那么,怎么返回一個(gè)長(zhǎng)度可變的隨機(jī)字符串呢?很簡(jiǎn)單,將 DBMS_RANDOM.STRING 和 DBMS_RANDOM.VALUE 函數(shù)結(jié)合一下就可以了。例如:
CALL dbms_random.seed(1); SELECT dbms_random.string('p', trunc(dbms_random.value(10,21))) AS random_string FROM dual; RANDOM_STRING | ------------------| qB!U5t^a6ZFUoIw|O^|
以上示例返回了一個(gè)隨機(jī)長(zhǎng)度大于等于 10 且小于等于 20,由任意可打印字符組成的隨機(jī)字符串。
生成隨機(jī)日期
將指定日期或者時(shí)間戳增加一個(gè)隨機(jī)的數(shù)字,就可以得到隨機(jī)的日期和時(shí)間戳。例如:
CALL dbms_random.seed(1); SELECT trunc(date '2020-01-01'+dbms_random.value(0,31)) rand_date, timestamp '2020-01-01 00:00:00'+dbms_random.value(0,31) rand_ts FROM dual; RAND_DATE |RAND_TS | -------------------|-------------------| 2020-01-24 00:00:00|2020-01-27 16:07:37|
以上示例返回了 2020 年 1 月中的某個(gè)隨機(jī)日期和時(shí)間戳。
獲取隨機(jī)記錄
對(duì)于查詢語(yǔ)句,如果返回多行數(shù)據(jù),DBMS_RANDOM 程序包中的函數(shù)會(huì)返回不同的隨機(jī)數(shù)據(jù)。例如:
CALL dbms_random.seed(1); SELECT dbms_random.value FROM employee; VALUE | ----------------------------------------| 0.75096444209816859425547820733985992585| 0.86038577935739084599473227591041135085| 0.36531856164744564910966598428812048036| ...
利用這個(gè)特性,我們可以從表中返回隨機(jī)的數(shù)據(jù)行。例如:
CALL dbms_random.seed(1); SELECT emp_id, emp_name FROM employee ORDER BY dbms_random.value FETCH FIRST 5 ROWS ONLY; EMP_ID|EMP_NAME | ------|---------| 10|廖化 | 24|簡(jiǎn)雍 | 20|蔣琬 | 6|魏延 | 4|諸葛亮 |
以上示例從 employee 表中返回了隨機(jī)的 5 行數(shù)據(jù)。
另外,Oracle 還提供了一個(gè) SAMPLE 子句,可以用于返回按照百分比指定的隨機(jī)抽樣數(shù)據(jù)。例如:
SELECT emp_id, emp_name FROM employee sample (10) seed(1); EMP_ID|EMP_NAME | ------|---------| 4|諸葛亮 | 5|黃忠 | 16|周倉(cāng) |
以上示例返回了 employee 表中抽樣 10% 的隨機(jī)數(shù)據(jù)(employee 表共計(jì)有 25 條數(shù)據(jù)),seed 用于設(shè)置隨機(jī)抽樣的種子。
⚠️SAMPLE 子句是一種基于數(shù)據(jù)庫(kù)統(tǒng)計(jì)信息的預(yù)估,如果統(tǒng)計(jì)數(shù)據(jù)不準(zhǔn)確,查詢結(jié)果可能會(huì)存在較大偏差。
生成 UUID
UUID(Universal Unique Identifier)或者 GUID(Globally Unique Identifier)是一個(gè) 128 比特的數(shù)字,可以用于唯一標(biāo)識(shí)每個(gè)網(wǎng)絡(luò)對(duì)象或資源。由于它的生成機(jī)制,一個(gè) UUID 可以保證幾乎不會(huì)與其他 UUID 重復(fù),因此常常用于生成數(shù)據(jù)庫(kù)中的主鍵值。
Oracle 提供了一個(gè)系統(tǒng)函數(shù) SYS_GUID(),可以用于生成 GUID。例如:
SELECT rawtohex(sys_guid()) FROM dual; RAWTOHEX(SYS_GUID()) | --------------------------------| ACCDB38D17FA1103E05579D90B3808D7|
如果想要生成帶中劃線(-)的 UUID,可以創(chuàng)建以下自定義函數(shù):
CREATE OR REPLACE FUNCTION new_guid RETURN varchar2 AS lv_guid varchar(32); BEGIN lv_guid:=rawtohex(sys_guid()); RETURN substr(lv_guid,1,8) || '-' ||substr(lv_guid,9,4) || '-' ||substr(lv_guid,13,4)|| '-' ||substr(lv_guid,17,4)|| '-' ||substr(lv_guid,21,12); END; /
new_guid 函數(shù)只是基于系統(tǒng)函數(shù) sys_guid 返回的結(jié)果增加了 4 個(gè)中劃線。試用一下:
SELECT new_guid() FROM dual; NEW_GUID() | ------------------------------------| ACCDB38D-17FD-1103-E055-79D90B3808D7|
總結(jié)
本文總結(jié)了在 Oracle 數(shù)據(jù)庫(kù)中使用系統(tǒng)程序包 DBMS_RANDOM 生成隨機(jī)數(shù)據(jù)的方法,包括隨機(jī)數(shù)字、驗(yàn)證碼、隨機(jī)字符串以及隨機(jī)日期和時(shí)間等,同時(shí)還介紹了如何從表中返回隨機(jī)記錄,以及如何生成 UUID。
到此這篇關(guān)于Oracle生成隨機(jī)數(shù)字、字符串、日期、驗(yàn)證碼及 UUID的方法的文章就介紹到這了,更多相關(guān)Oracle生成隨機(jī)數(shù)UUID內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Oracle11.2.0.1如何升級(jí)到11.2.0.3 Oracle同版本升級(jí)
這篇文章主要為大家詳細(xì)介紹了Oracle11.2.0.1如何升級(jí)到11.2.0.3的過(guò)程,Oracle同版本升級(jí)的方法,感興趣的小伙伴們可以參考一下2016-07-07Oracle下的Java分頁(yè)功能_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
分頁(yè)的時(shí)候返回的不僅包括查詢的結(jié)果集(List),而且還包括總的頁(yè)數(shù)(pageNum)、當(dāng)前第幾頁(yè)(pageNo)等等信息,所以我們封裝一個(gè)查詢結(jié)果PageModel類,具體實(shí)現(xiàn)代碼,大家參考下本文2017-08-08淺析常用數(shù)據(jù)庫(kù)的自增字段創(chuàng)建方法匯總
本篇文章是對(duì)常用數(shù)據(jù)庫(kù)的自增字段創(chuàng)建方法進(jìn)行了全面的匯總介紹,需要的朋友參考下2013-07-07探討:Oracle數(shù)據(jù)庫(kù)查看一個(gè)進(jìn)程是如何執(zhí)行相關(guān)的實(shí)際SQL語(yǔ)句
本篇文章是對(duì)Oracle數(shù)據(jù)庫(kù)查看一個(gè)進(jìn)程是如何執(zhí)行相關(guān)的實(shí)際SQL語(yǔ)句進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Oracle中分析函數(shù)over()的用法及說(shuō)明
這篇文章主要介紹了Oracle中分析函數(shù)over()的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02Oracle數(shù)據(jù)泵(Data Dump)使用過(guò)程當(dāng)中經(jīng)常會(huì)遇到一些奇奇怪怪的錯(cuò)誤案例
從oracledatabase 10g開(kāi)始引入了data pump(數(shù)據(jù)泵)工具,它提供了一種基于服務(wù)器的數(shù)據(jù)導(dǎo)出導(dǎo)入使用程序。 所有的data pump都作為一個(gè)服務(wù)器進(jìn)程,數(shù)據(jù)不再必須由一個(gè)客戶程序處理。Data Pump工具的導(dǎo)出和導(dǎo)入實(shí)現(xiàn)Oracle數(shù)據(jù)庫(kù)之間數(shù)據(jù)的傳輸。2014-09-09ORACLE數(shù)據(jù)庫(kù)日常維護(hù)知識(shí)點(diǎn)總結(jié)
這篇文章主要介紹了ORACLE數(shù)據(jù)庫(kù)日常維護(hù)知識(shí)點(diǎn)總結(jié),對(duì)于維護(hù)oracle數(shù)據(jù)庫(kù)的朋友可以參考下2016-06-06