MySQL 使用 CTE 创建视图

0 mysql cte view mysql-5.6

我已经成功地在 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
Run Code Online (Sandbox Code Playgroud)

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

And*_*y M 6

首先,从 8.0 版开始,MySQL 就在最近开始支持 CTE (正如其他人所提到的)。您收到的语法错误似乎表明您使用的是旧版本。因此,您的数据库服务器需要升级1

除此之外,您的CREATE VIEW语句还存在一些问题需要解决才能使其在 MySQL 中工作。

  1. 方括号分隔符。

    使用方括号分隔名称,如语句的第一行:

    CREATE VIEW [dbo].[vw_PurchParent] as
    
    Run Code Online (Sandbox Code Playgroud)

    特定于 Transact-SQL。对于 MySQL,您需要用双引号 ( ") 或反引号 ( `)替换它们。或者,在这种情况下,您可以完全省略它们,因为名称仅包含字母和下划线,允许在名称中使用而无需分隔。

  2. 架构名称。

    在 SQL Server 中,数据库包含架构,架构包含对象(表、视图、函数、存储过程等)。因此,一个对象的全名由三部分组成:

    数据库.模式.对象
    

    当它只有两部分时,例如在这种情况下 ( [dbo].[vw_PurchParent]),则将其解释为

    模式对象
    

    但是,MySQL 不支持数据库中的模式。当一个对象引用有两部分时,它被解释为

    数据库对象
    

    因此,dbo.在为 MySQL 调整脚本时,您可能希望删除视图名称的一部分。

  3. 缺少关键字RECURSIVE

    此视图定义中的 CTE 是递归 CTE 2。MySQL 支持递归 CTE,但与 SQL Server 不同,它要求RECURSIVE在一个或多个 CTE 中指定关键字WITH子句中的是递归。

    因此,WITH定义的行将需要重写为

    WITH RECURSIVE cte AS
    
    Run Code Online (Sandbox Code Playgroud)
  4. 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 需要具有的特定结构。

  • @RickJames:当然。如果即使是单个语句也会产生如此多的差异,那么解决所有这些差异应该占用一本书的一章。 (2认同)