翻譯|使用教程|編輯:楊鵬連|2021-03-18 11:26:17.567|閱讀 234 次
概述:使用舊式聯接語法沒有任何優勢。如果SQL提示標識了它在舊版代碼中的使用,則重寫語句以使用ANSI標準的連接語法將簡化和改進代碼。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
SQL Prompt是一款實用的SQL語法提示工具。SQL Prompt根據數據庫的對象名稱、語法和代碼片段自動進行檢索,為用戶提供合適的代碼選擇。自動腳本設置使代碼簡單易讀--當開發者不大熟悉腳本時尤其有用。SQL Prompt安裝即可使用,能大幅提高編碼效率。此外,用戶還可根據需要進行自定義,使之以預想的方式工作。
使用舊式聯接語法沒有任何優勢。如果SQL提示標識了它在舊版代碼中的使用,則重寫語句以使用ANSI標準的連接語法將簡化和改進代碼。
SQL Prompt實現了一個靜態代碼分析規則ST001,該規則將在開發和測試工作期間自動檢查代碼是否出現非ANSI標準的JOIN語法。
SQL的“舊樣式” Microsoft / Sybase JOIN樣式已使用= *和* =語法,已棄用,不再使用。當數據庫引擎級別為10(SQL Server 2008)或更高版本(兼容級別100)時,使用此語法的查詢將失敗。ANSI-89表引用列表(FROM表A,表B)仍然僅是INNER JOIN的ISO標準。這些樣式都不值得使用。自ANSI SQL-92發布以來,就一直最好指定所需的連接類型:INNER,LEFT OUTER,RIGHT OUTER,FULL OUTER和CROSS。盡管可以選擇任何受支持的JOIN樣式,而不會影響SQL Server使用的查詢計劃,但使用ANSI標準語法將使您的代碼更易于理解,更一致,并且可移植到其他關系數據庫系統中。
舊式外部聯接已過時
當SQL Server從Sybase派生時,它繼承了其舊的非標準Transact-SQL語法用于聯接,其中分別包括左和右外部聯接的=和=語法。
從第一個表(外部聯接的“外部成員”)中選擇的左外部聯接運算符* =,滿足語句限制的所有行。僅當該行的連接條件匹配時,第二個表(“內部成員”)才會生成值;否則,它提供空值。相反,對于右外部聯接運算符= *,第二個表成為“外部成員”,從中選擇所有符合條件的行。
即使支持這些語法,也存在一些限制。您不能在HAVING子句中包含Transact-SQL外部聯接,也不能在與舊式外部聯接相同的表達式中執行其他INNER JOIN。此外,外部連接語法(* =或= *)并不總是給出正確的結果,有時在指定外部連接時使用交叉連接。
無論如何,此語法在SQL Server 2005及更高版本中已被棄用,并在SQL Server 2008中停止工作。清單1的目的是查詢pubs數據庫,其目的是返回沒有相應作者的所有標題。
--all titles without an author SELECT ti.title + Coalesce( ' (' + ti.type + ') -' + ti.pub_id,' (Unknown category)') AS publication FROM dbo.titles AS ti, dbo.titleauthor AS Ta where ti.title_id *= Ta.title_id AND Ta.title_id IS NULL;清單1
Msg 102, Level 15, State 1, Line 6
Incorrect syntax near '*='.
如果仍然有使用此語法的查詢,則在升級到SQL Server 2012之前,必須重寫它們以使用清單2中所示的ANSI標準語法,因為不再支持兼容性級別90。
--all titles without an author SELECT ti.title + Coalesce( ' (' + ti.type + ') -' + ti.pub_id,' (Unknown category)') AS publication FROM dbo.titles AS ti LEFT OUTER JOIN dbo.titleauthor AS Ta ON ti.title_id = Ta.title_id WHERE Ta.title_id IS NULL ORDER BY ti.title清單2
得到以下結果:
內部聯接的表引用語法是ANSI標準的一部分,因此仍受支持。清單3使用了它,并將返回與其發布者居住在同一城市的所有作者。
–(舊語法)與發布者居住在同一城市的作者
--(Old Syntax)authors that live in the same city as their publishers SELECT authors.au_fname + ' ' + authors.au_lname AS Author, publishers.pub_name AS Publisher, publishers.city FROM dbo.authors, dbo.titleauthor, dbo.titles, dbo.publishers WHERE authors.au_id = titleauthor.au_id AND titleauthor.title_id = titles.title_id AND titles.pub_id = publishers.pub_id AND publishers.city = authors.city清單3
清單4顯示了使用ANSI-92標準的相同代碼,其中我們使聯接類型明確。
--(Newer Syntax) authors that live in the same city as their publishers SELECT authors.au_fname+ ' '+authors.au_lname AS Author, publishers.pub_name AS Publisher, publishers.city FROM dbo.authors INNER JOIN dbo.titleauthor ON authors.au_id = titleauthor.au_id INNER JOIN dbo.titles ON titleauthor.title_id = titles.title_id INNER JOIN dbo.publishers ON titles.pub_id = publishers.pub_id WHERE publishers.city = authors.city清單4
兩者給出的結果相同,執行計劃相同。
無論如何,即使仍支持該舊式語法,也沒有遺憾的理由。例如,您如何使用舊風格的聯接語法確定與發布者居住在不同城市的作者所占的百分比?這將是一個使用方括號和子查詢的外觀復雜的查詢。使用更新的語法,它很容易編寫,也很容易理解其邏輯。
--proportion of authors who live in the same city as their publishers SELECT Sum(CASE WHEN publishers.city IS NULL THEN 1 ELSE 0 END) AS [different city], Count(*) AS total, (Sum(CASE WHEN publishers.city IS NULL THEN 1 ELSE 0 END) * 100) / Count(*) AS percentage FROM dbo.authors INNER JOIN dbo.titleauthor ON authors.au_id = titleauthor.au_id INNER JOIN dbo.titles ON titleauthor.title_id = titles.title_id LEFT OUTER JOIN dbo.publishers ON titles.pub_id = publishers.pub_id AND publishers.city = authors.city清單5
結論
將舊式聯接語法留在遺留代碼中沒有任何優勢。如果發現此代碼異味,它將改進并簡化代碼以重寫語句以使用ANSI標準連接語法。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: