成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Oracle因數(shù)據(jù)不一致而導(dǎo)致的隱式轉(zhuǎn)換錯誤一例

   今天,開發(fā)同事說他在測試庫執(zhí)行一條SQL的時候,報ORA-01722: invalid number錯誤,但是在生產(chǎn)庫和灰度庫執(zhí)行同一條SQL卻能夠正常執(zhí)行,SQL如下:
  
  select ItemStatus from BUS_CONTRACT where SerialNo=2016033100000047;

  問了一下開發(fā)同事基本信息,得知SerialNo的字段類型為varchar2類型,此時未加引號,肯定是進行了隱式轉(zhuǎn)換,但是為什么在生產(chǎn)庫和灰度庫卻能夠執(zhí)行成功呢?帶著如此疑問,進行了以下慢慢的摸索……
  
    最初猜測是不是其他數(shù)據(jù)行的SerialNo字段存在帶有字符的數(shù)據(jù)呢,但是查看了一下BUS_CONTRACT表的表結(jié)構(gòu),發(fā)現(xiàn)BUS_CONTRACT表的主鍵就是SerialNo字段,此時的查詢,應(yīng)該是可以走主鍵索引而不會全表掃描的,即便是其他數(shù)據(jù)行有帶字符的數(shù)據(jù),也不會被掃描到才是,可為什么會報錯呢?

  后來通過搜索網(wǎng)絡(luò)上的文章,得知oracle在隱式轉(zhuǎn)換時,如果是VARCHAR2->NUMBER轉(zhuǎn)換,則不會導(dǎo)致索引失效,而如果是NUMBER->VARCHAR2的轉(zhuǎn)換,此時則會讓索引失效,很明顯本次查詢是NUMBER->VARCHAR2的轉(zhuǎn)換,此時即便是有索引,oracle也不會走索引掃描而只會走全表掃描,查看其執(zhí)行計劃,果然如此:

SQL> set autotrace traceonly
SQL>
SQL> select ItemStatus from BUS_CONTRACT where SerialNo=2016033100000047;
ERROR:
ORA-01722: invalid number

no rows selected

Execution Plan
----------------------------------------------------------
Plan hash value: 809618537

---------------------------------------------------------------------------------------

| Id  | Operation  | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

---------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     1 |    21 |   661 (1)| 00:00:08 |

|*  1 |  TABLE ACCESS FULL| BUS_CONTRACT |     1 |    21 |   661 (1)| 00:00:08 |

---------------------------------------------------------------------------------------



Predicate Information (identified by operation id):
---------------------------------------------------


   1 - filter(TO_NUMBER("SERIALNO")=2016033100000047)


Statistics
----------------------------------------------------------
   0      recursive calls
   1      db block gets
 2341  consistent gets
 2392  physical reads
 0        redo size
529     bytes sent via SQL*Net to client
519     bytes received via SQL*Net from client
 2        SQL*Net roundtrips to/from client
 0        sorts (memory)
 0        sorts (disk)
 0        rows processed


SQL>
SQL>


  然后,通知開發(fā)同事,讓他通過如下SQL看一下SerialNo字段是不是存在臟數(shù)據(jù):

  select ItemStatus,SerialNo from BUSI_CONTRACT;

  開發(fā)人員反饋,果然是有一條記錄不是純數(shù)字而帶有一些字符,讓其刪除該數(shù)據(jù)之后,查詢正常。

  建議跟隱式轉(zhuǎn)換有關(guān)的SQL,最好還是帶上引號,如下是SQL語句select ItemStatus from BUSI_CONTRACT where SerialNo='2016033100000047';的執(zhí)行計劃:

SQL>
SQL> select ItemStatus from BUS_CONTRACT where SerialNo='2016033100000047';

Execution Plan
----------------------------------------------------------
Plan hash value: 338903438

----------------------------------------------------------------------------------------------------

| Id  | Operation    | Name   | Rows  | Bytes | Cost (%CPU)| Time   |

----------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT    |   | 1 | 21 | 2   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| BUS_CONTRACT    | 1 | 21 | 2   (0)| 00:00:01 |

|*  2 |   INDEX UNIQUE SCAN    | PK_BUS_CONTRACT | 1 |   | 1   (0)| 00:00:01 |

----------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SERIALNO"='2016033100000047')

Statistics
----------------------------------------------------------
 1     recursive calls
 0     db block gets
 4     consistent gets
 0     physical reads
 0     redo size
528  bytes sent via SQL*Net to client
519  bytes received via SQL*Net from client
 2     SQL*Net roundtrips to/from client
 0     sorts (memory)
 0     sorts (disk)
 1     rows processed


  性能明顯優(yōu)于不帶引號的,因為此時沒有經(jīng)歷隱式轉(zhuǎn)換,SQL執(zhí)行走索引掃描了。


  結(jié)論:1.涉及到隱式轉(zhuǎn)換到字段最好加上引號,否則不會走索引;
             2.隱式轉(zhuǎn)換如果是VARCHAR2->NUMBER轉(zhuǎn)換,則不會導(dǎo)致索引失效,而如果是NUMBER->VARCHAR2的轉(zhuǎn)換,此時則會讓索引失效;
             3.之所以NUMBER->VARCHAR2會讓索引失效,應(yīng)該是轉(zhuǎn)換為where to_number(name) = 123。

本文名稱:Oracle因數(shù)據(jù)不一致而導(dǎo)致的隱式轉(zhuǎn)換錯誤一例
URL地址:http://jinyejixie.com/article14/pgeide.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、App開發(fā)、外貿(mào)建站定制開發(fā)、云服務(wù)器、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
攀枝花市| 安图县| 安仁县| 广安市| 五台县| 大安市| 汝南县| 曲沃县| 中超| 沾益县| 保靖县| 呼和浩特市| 开远市| 河池市| 育儿| 建瓯市| 凤凰县| 谢通门县| 安福县| 大埔区| 额尔古纳市| 察雅县| 临潭县| 静宁县| 故城县| 江都市| 台安县| 明水县| 龙游县| 历史| 辽阳市| 建湖县| 虹口区| 三明市| 静安区| 金门县| 凤山市| 皮山县| 什邡市| 嵊泗县| 陆河县|