Mysql

MySQL 使用 CTE 創建視圖

  • May 13, 2019

我已經在 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 中工作。

  1. 方括號分隔符。

使用方括號來分隔名稱,如語句的第一行:

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
  1. 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 需要具有的特定結構。

引用自:https://dba.stackexchange.com/questions/237944