在 CREATE VIEW 内的 WITH...AS 中使用多个表表达式时出现“找不到对象”错误

Posted

技术标签:

【中文标题】在 CREATE VIEW 内的 WITH...AS 中使用多个表表达式时出现“找不到对象”错误【英文标题】:"Object not found" error when using multiple table expressions in WITH...AS inside of CREATE VIEW 【发布时间】:2021-01-11 14:34:55 【问题描述】:

我正在尝试基于 HSQLDB(版本 2.5.1)中的复杂查询创建视图。

查询看起来像这样(为清楚起见进行了简化),还包括表的 DDL:

DROP VIEW TEST_VIEW IF EXISTS;

DROP TABLE TEST_1 IF EXISTS;
CREATE TABLE TEST_1 (
    contentid VARCHAR(10),
    contenttype VARCHAR(10),
    downloaddate TIMESTAMP
);

DROP TABLE TEST_2 IF EXISTS;
CREATE TABLE TEST_2 (
    dbid INTEGER,
    contentid VARCHAR(10),
    version VARCHAR(10)
);

CREATE VIEW TEST_VIEW AS
WITH a AS (
    SELECT CONTENTID, count(*) AS amount
    FROM TEST_2
    GROUP BY CONTENTID
),
    b AS (
        SELECT CONTENTID, amount
        FROM a
    )
SELECT b.CONTENTID, b.amount, i.DOWNLOADDATE
FROM b /* error here */
    JOIN TEST_1 i ON i.CONTENTID = b.CONTENTID
ORDER BY b.CONTENTID;

但是,它失败并出现以下错误:

[42501][-5501] 用户缺少权限或找不到对象:在语句 [CREATE VIEW TEST_VIEW AS......中加入......

当用作SELECT(没有CREATE VIEW...AS)时,相同的查询运行良好。

另外,如果WITH...AS语句中只有一个表表达式,则视图创建成功,如下所示:

CREATE VIEW TEST_VIEW AS
WITH a AS (
    SELECT CONTENTID, count(*) AS amount
    FROM TEST_2
    GROUP BY CONTENTID
)
SELECT a.CONTENTID, a.amount, i.DOWNLOADDATE
FROM a
    JOIN TEST_1 i ON i.CONTENTID = a.CONTENTID
ORDER BY a.CONTENTID;

看起来在第一条语句中,数据库引擎尝试将“JOIN”解析为表“b”的表别名。

是否存在我没​​有注意到的语法错误,或者 HSQLDB 不支持 WITH...ASCREATE VIEW 内的多个表表达式?

编辑:更新示例查询以包含表 DDL 以确保完整性。

【问题讨论】:

您可以单独运行查询吗? (即没有 CREATE VIEW 部分。) 是的,它可以独立运行并返回预期的数据。 【参考方案1】:

HSQLDB 支持创建这种类型的视图。

由于您没有提供表定义,我尝试对 DatabaseManager 生成的测试表进行类似查询,结果成功。请报告表格。

CREATE VIEW REPORT_LINKED_IDS AS
WITH a AS (
    SELECT PRODUCTID, count(*) AS amount
    FROM ITEM
    GROUP BY PRODUCTID
),
    b AS (
        SELECT PRODUCTID, amount
        FROM a
    )
SELECT b.PRODUCTID, b.amount, i.NAME, i.PRICE
FROM b
    JOIN PRODUCT i ON i.ID = b.PRODUCTID
ORDER BY b.PRODUCTID;                  

【讨论】:

在原始问题中添加了表定义。 使用 HSQLDB 2.5.1 DatabaseManagerSwing 测试了您的新示例(双击要执行的 jar)并成功创建了视图。您可以检查的内容包括您的 HSQLDB 版本以及您可能用于运行查询的任何工具。 感谢您对此进行调查。问题确实出在用于运行查询的工具 (IntelliJ IDEA) 上。【参考方案2】:

感谢@fredt 的建议,我已经确认问题在于尝试在 IntelliJ IDEA (2020.1) 中使用此查询。当使用另一个工具(在我的例子中为 DbVisualizer)时,查询工作正常,并且在同一个数据库中成功创建了视图。此外,在 DB 中创建视图后,IntelliJ IDEA 在尝试连接到此 DB 时会在同一个单词“JOIN”上引发异常 - 错误类似于:The specified database user/password combination is rejected: org.hsqldb.HsqlException: unexpected token: NOT。与上述问题中的评论类似,我已通过手动编辑 .script 文件从错误中恢复。

至少有 2 个可能的选项可以解决此问题:

第一种解决方案: 将 SQL 查询重构为在 WITH 子句中只有一个表。就我而言,我只是将第一个表移动到 FROM 子句中的选择表达式,如下所示:

CREATE VIEW TEST_VIEW AS
WITH b AS (
        SELECT CONTENTID, amount
        FROM (
            SELECT CONTENTID, count(*) AS amount
            FROM TEST_2
            GROUP BY CONTENTID
        )
    )
SELECT b.CONTENTID, b.amount, i.DOWNLOADDATE
FROM b
    JOIN TEST_1 i ON i.CONTENTID = b.CONTENTID
ORDER BY b.CONTENTID;

第二个解决方案:使用不同的工具来处理数据库,或者在 IDEA 中修复问题。

【讨论】:

以上是关于在 CREATE VIEW 内的 WITH...AS 中使用多个表表达式时出现“找不到对象”错误的主要内容,如果未能解决你的问题,请参考以下文章

CREATE VIEW - 定义一个视图

create view in view

使用 sqlalchemy_utils.create_materialized_view() 时如何自动创建索引

当 docker 容器内的数据发生变化时,Create-react-app 服务器不会重新编译

ScrollTo indexPath 在 Collection View Cell 内的 Collection View (Nested CollectionView)

将 View 定位在 ImageView 内的 Drawable 之上