MySQL 使用 CTE 創建視圖
我已經在 SQL Server 中成功創建了一個 VIEW,如下所示。但是當我在 MySql 中嘗試同樣的方法時,錯誤來了。
SQL 伺服器命令:
CREATE VIEW [dbo].[vw_PurchParent] as WITH cte AS ( SELECT a._Id, a._parentId, a._name, a._IsLedger FROM tbl_ChartOfAcc a WHERE _Id = 1 UNION ALL SELECT a._Id, a._parentid, a._Name, a._IsLedger FROM tbl_ChartOfAcc a JOIN cte c ON a._parentId = c._id ) SELECT * FROM cte where _IsLedger = 'Y' GO
MySQL 中的錯誤:
1064 - 您的 SQL 語法有錯誤;檢查與您的 MySQL 伺服器版本相對應的手冊,以在第 1 行的 ‘cte AS( SELECT a._Id, a._parentId, a._name, ’ 附近使用正確的語法
伺服器版本:5.6.41 -84.1 - Percona Server (GPL),版本 84.1,修訂版 b308619
您需要在 MySQL中使用 8.0 進行CTE
首先,MySQL 從最近開始支持 CTE,從 8.0 版開始(正如其他人所提到的)。您收到的語法錯誤似乎表明您使用的是舊版本。因此,您的數據庫伺服器需要升級1。
除此之外,您的
CREATE VIEW
語句還有一些問題需要解決才能使其在 MySQL 中工作。
- 方括號分隔符。
使用方括號來分隔名稱,如語句的第一行:
CREATE VIEW [dbo].[vw_PurchParent] as
特定於 Transact-SQL。對於 MySQL,您需要用雙引號 (
"
) 或反引號 ( ```) 替換它們。或者,在這種情況下,您可以完全省略它們,因為名稱僅包含字母和下劃線,允許在名稱中使用它們而無需分隔。 2. 架構名稱。在 SQL Server 中,數據庫包含架構,架構包含對象(表、視圖、函式、儲存過程等)。因此,一個對象的全名由三部分組成:
*數據庫.schema.object*
當它只有兩個部分時,例如在這種情況下 (
[dbo].[vw_PurchParent]
),那麼它被解釋為*模式.對象*
但是,MySQL 不支持數據庫中的模式。當一個對象引用有兩個部分時,它被解釋為
*數據庫對象*
因此,在為 MySQL 調整腳本時,您可能希望刪除
dbo.
視圖名稱的一部分。 3. 缺少關鍵字RECURSIVE
。此視圖定義中的 CTE 是遞歸 CTE 2。MySQL 支持遞歸 CTE,但與 SQL Server 不同,它要求在子句中
RECURSIVE
的一個或多個 CTE 遞歸時指定關鍵字。WITH
因此,
WITH
定義的行將需要重寫為WITH RECURSIVE cte AS
GO
關鍵字。腳本末尾的
GO
關鍵字特定於 SQL Server 平台,儘管它本身不是 Transact-SQL 方言的一部分。相反,它是一些 SQL Server 客戶端工具(SSMS、sqlcmd、現已棄用的 osql)解釋的指令。它表示一批語句的結束。在這種情況下,它應該簡單地替換為分號 (;
)。請注意,通常始終以分號結束語句也是一種很好的做法,分號是 SQL 中的標準語句分隔符。
1或者,您也可以考慮切換到 MariaDB。MariaDB 是 MySQL 的一個分支,因此它在許多方面與 MySQL 兼容,包括 SQL 方言方面。與此同時,眾所周知,MariaDB 經常在 MySQL 之前引入高級語言特性——包括 CTE、視窗函式等。例如,如前所述,CTE 已在一年前(2018 年 4 月)發布的 8.0 版中引入 MySQL。相比之下,截至撰寫本文時,MariaDB 已經支持 CTE 大約 2-3 年了。(CTE 於 2016 年首次添加到版本 10.2;該版本於 2017 年成為穩定版本。)
2它表示一個 UNION ALL 查詢,在第二個分支中具有自引用,這是遞歸 CTE 需要具有的特定結構。