避免使用select * 的最特別的理由


快速搜索Google或Bing,你會無數的文章會告訴你數據庫中顯示使用“ SELECT *”是一件可怕的事情。你的代碼將更加脆弱。這對你的數據字典不利。使用后,你最終會遇到沖突等等。你可以從Markus Winand的文章(https://use-the-index-luke.com/blog/2013-08/its-not-about-the-star-stupid)中找到更合理的論點,但最終在大多數情況下,潛在的弊端超過了使用SELECT *帶來的任何便利好處。

(我之所以說“大多數”,是因為PL/SQL是少數幾種語言之一,它的%ROWTYPE語法和DML的VALUES/SET ROW子句可以使你避免很多風險。這也是PL/SQL為什么如此酷的一個原因)。

但是,這可能是你會想避免選擇SELECT *的最奇怪的原因。我將從一個簡單的表T開始,並命名為CHILD和PARENT列,因為我將使用遞歸子查詢因子分解功能來查詢該表:

SQL> create table t(child,parent ) as select 2,1 from dual;

Table created.

由於只有一行數據,從遞歸查詢得到的結果並不是特別令人興奮

SQL> with recursive(chd,par) as (
  2  select child,parent
  3  from t
  4  union all
  5  select t.child,t.parent
  6  from t,recursive
  7  where recursive.chd=t.parent
  8  )
  9  select *
 10  from recursive;

       CHD        PAR
---------- ----------
         2          1

這里要注意的關鍵是第2行和第5行。正如你對任何UNION ALL查詢所期望的那樣,UNION ALL第一部分中的列數必須與UNION ALL第二部分中的列數相匹配。

在第5行中,我查詢表T中的CHILD和PARENT列,精明的讀者已經發現,這是T中的所有列,並且與表的定義中的順序相同。因此,讓我們看看當我違背傳統觀點並將其替換為SELECT *時會發生什么。

SQL> with recursive (chd,par) as (
  2     select child,parent
  3     from t
  4     union all
  5     select t.*
  6     from t, recursive
  7     where recursive.chd = t.parent
  8     )
  9     select *
 10     from recursive;
        select t.*
        *
ERROR at line 5:
ORA-01789: query block has incorrect number of result columns

要了解為什么會這樣,我們需要仔細查看遞歸子查詢分解的文檔,其中指出:

“The number of column aliases following WITH query_name and the number of columns in the SELECT lists of the anchor and recursive query blocks must be the same.”

  

ORA-01789錯誤提示此檢查是在語法處理的早期完成的,然后將星號擴展為列。因此,在UNION ALL的第二部分上只有一個項(早期表示即在將星號擴展成列名之前,這樣只是將星號當成了一個列了,因此不匹配)。通過在SQL中添加亂碼,可以進一步了解此檢查的早期假設。

SQL> with recursive (chd,par) as (
  2    select child,parent
  3    from t
  4    union all
  5    select blahblahblah.*
  6    from t, recursive
  7    where recursive.chd = t.parent
  8  )
  9  select *
 10  from recursive;
  select blahblahblah.*
  *
ERROR at line 5:
ORA-01789: query block has incorrect number of result columns

即使引用了不存在的“ blahblahblah”,我們得到的第一個錯誤也不是引用不存在,而是列數。該語句在到達數據字典進行進一步驗證之前,未通過第一次語法檢查。

因此,當涉及到遞歸查詢子處理時,請確保將這些列列出來!

 

 

原文地址:https://connor-mcdonald.com/2020/10/12/the-weirdest-reason-to-avoid-select/


免責聲明!

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



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