orcle not like不建議使用(not like所踩過的坑!)


1.情景展示

  現在有一張表,需要將表中某字段的值不是以指定字符開頭的列進行刪除,如何實現? 

2.問題分析

  錯誤方案一:同事想到的是:這種方式

  咱們來看一下,這個表總共有多少條數據

  本來表數據總共才4萬多條數據,然而使用上面的查詢方式,卻查出了1多個億的數據,真不知道這數據庫是怎么想的。

  錯誤方案二:既然不行,我首先想到的是:使用not like實現,實踐結果如下:

  再來看一下,使用like查詢有多少條數據。

  總共的數據為:40059+3972=44031條 數據,比總表數44295要少,也就是說:使用not like查詢會遺漏數據,具體什么原因想不通。

3.解決方案

  正確方案一:not exists(),推薦使用

  既然not like不行,我就想到用了使用exists()實現。 

  先來查查符合條件的,使用exists()查詢一下與使用like的語句是否一致。

  結果一致,再看一下,使用not exists()的查詢結果

  算一下,與總數是否一致:40323+3972=44295,與結果一致,大功告成!

--查詢表中不是以0.1.2.開頭的數據(使用exists實現)
SELECT COUNT(1)
  FROM BASE_ORG_INFO T
 WHERE NOT EXISTS
 (SELECT 1
          FROM (SELECT ORGID FROM BASE_ORG_INFO WHERE ORGSEQ LIKE '0.1.2.%') S
         WHERE S.ORGID = T.ORGID)

  如何刪除這些數據?

--刪除表中某字段不是以0.1.2.開頭的數據(使用IN+EXISTS實現)
DELETE FROM BASE_ORG_INFO T2
 WHERE T2.ORGID IN (SELECT T.ORGID
                      FROM BASE_ORG_INFO T
                     WHERE NOT EXISTS (SELECT 1
                              FROM (SELECT ORGID
                                      FROM BASE_ORG_INFO
                                     WHERE ORGSEQ LIKE '0.1.2.%') S
                             WHERE S.ORGID = T.ORGID))

  執行結果:

  方案二:not in()

DELETE FROM BASE_ORG_INFO T2
 WHERE T2.ORGID IN
       (SELECT T.ORGID
          FROM BASE_ORG_INFO T
         WHERE T.ORGID NOT IN
               (SELECT ORGID FROM BASE_ORG_INFO WHERE ORGSEQ LIKE '0.1.2.%'))

  執行結果如下:

  20200617補充說明:

  如文末評論區二樓所言,此時,SELECT ORGID FROM BASE_ORG_INFO WHERE ORGSEQ LIKE '0.1.2.%'),需要確保ORGID不能為空,否則可能會出現漏刪

  (ORGID為空,ORGSEQ既有以0.1.2開頭的,也有不是以它開頭的,存在這種可能性)!

  但反過來說,只要確保ORGID非空,使用NOT IN()就不存在漏洞。

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:

 


免責聲明!

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



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