快速搜索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/
