使用DBMS_RANDOM過程引發的問題
這個問題其實是昨天問題所引發的。
動態返回結果的檢視:http://yangtingkun.itpub.net/post/468/490262
在上面的文章結尾提到了,利用變數構造動態檢視,可以建立很多有意思的物件。這裡就引出了一個有意思的問題,不過這個問題和動態檢視無關,而和最後一個使用DBMS_RANDOM包的例子有關。
SQL> create table t_id (id number);
Table created.
SQL> insert into t_id
2 select rownum
3 from dba_objects
4 where rownum <= 10000;
10000 rows created.
SQL> commit;
Commit complete.
最開始的時候,V_RANDOM檢視的定義和上一篇文章中的並不一致。當時的檢視是這樣建立的:
SQL> create or replace view v_random
2 as select *
3 from t_id
4 where id = round(dbms_random.value(1, 10000));
View created.
建立這個檢視後,發現這個檢視的訪問結果很奇怪:
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
ID
----------
4325
SQL> select * from v_random;
ID
----------
4012
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
ID
----------
1192
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
ID
----------
5860
SQL> select * from v_random;
ID
----------
5922
8077
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
ID
----------
3368
3449
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
ID
----------
5683
1551
4929
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
no rows selected
SQL> select * from v_random;
ID
----------
762
不光返回ID的值是隨機的,連返回結果的記錄數也是不確定的。有時返回1條、有時返回2條甚至3條,還有時根本不返回任何記錄。
開始以為DBMS_RANDOM包的用法有誤,簡單分析後發現問題和DBMS_RANDOM包有些關係,但是並非是用法錯誤。
原因在於DBMS_RANDOM.VALUE函式的呼叫並非是發生在語句執行之前,而是發生在語句執行之中。這樣說有點抽象,下面具體的描述一下。
以前寫過一篇文章,介紹Oracle是如何處理常量的:http://yangtingkun.itpub.net/post/468/20038
在文章中提到,對於常量而言,Oracle會在SQL語句執行之前將結果計算出來,而對於列的運算而言,需要對錶中每條記錄都進行運算。
如果Oracle這裡採用常量的計算方法,就會先執行DBMS_RANDOM.VALUE函式,從而得到一個固定的結果,那麼最終必然返回1條記錄。實際上也就是上一篇文章中展示的例子。
而現在的情況是,Oracle沒有提前計算DBMS_RANDOM.VALUE的值,而是針對T_ID表掃描的每條記錄都去呼叫函式DBMS_RANDOM.VALUE並和ID的值進行比較。顯然二者相等的機率極小,只有萬分之一的可能性。但是由於T_ID包含1W條記錄,因此這個機率極小的相等比較了1W次,導致最終查詢結果很可能返回1條甚至是多條記錄。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-612645/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 儲存過程單引號問題儲存過程
- 使用in out引數模式的過程模式
- 使用out引數模式的過程模式
- android開發過程中遇到的問題Android
- 記錄在使用Django開發過程中遇到的問題No.2Django
- Flutter開發過程中遇到的問題記錄Flutter
- 一次IO效能問題的發現過程
- 開發過程中mysql常見問題MySql
- 偶發的儲存過程呼叫效能問題的一次調優過程儲存過程
- 儲存過程訪問其他使用者的表的問題儲存過程
- docker使用redis過程出現的問題記錄DockerRedis
- 使用HttpClient過程中常見的一些問題HTTPclient
- 使用javamail發信過程中的一些問題及解決方法JavaAI
- DBMS_RANDOM使用random
- 儲存過程輸入引數型別定義引起的問題儲存過程型別
- 儲存過程問題。。儲存過程
- 皮膚開發過程中遇到的3個問題
- 教育類app開發過程中,需要避免的問題APP
- iOS 彈幕開發過程碰到的問題總結iOS
- Composer 使用過程中遇到的問題和解決方案
- Mac電腦使用imazing過程中遇到的問題Mac
- npm install 使用過程出現的問題總結NPM
- vue專案開發過程常見問題Vue
- 記錄開發過程一個路由問題路由
- 【DBMS_RANDOM】使用 DBMS_RANDOM包生成隨機字串random隨機字串
- 一個儲存過程的問題!儲存過程
- 爬蟲過程中遇到的問題爬蟲
- 開發過程中遇到問題該怎麼辦?
- @AllArgsConstructor與@Value共同使用引發的報錯問題Struct
- Android自帶Json庫使用引發的問題AndroidJSON
- php使用mysqlnd引發的一些問題處理PHPMySql
- ng-template 使用過程中預設引數不能按照期望工作的問題單步除錯除錯
- 直播賣貨APP開發過程中的最佳化問題APP
- 前端開發過程常見問題,比如JavaScript變數的提升前端JavaScript變數
- 安裝yeoman,grunt過程中的問題
- mysql多次呼叫儲存過程的問題MySql儲存過程
- 學習vue過程中遇到的問題Vue
- STATSPACK安裝過程中遇到的問題