使用 HSQLDB 生成基于 CTE 的序列

Phi*_*all 5 sql sequence hsqldb common-table-expression

我正在使用递归公用表表达式来获取一批序列号。以下查询适用于 Postgres、SQL Server 和 H2(减去该VALUES部分)。

WITH RECURSIVE t(n, level_num) AS (
    SELECT next value for seq_parent_id as n,
           1 as level_num
      FROM (VALUES(0))

    UNION ALL

    SELECT next value for seq_parent_id as n,
           level_num + 1 as level_num
      FROM t
     WHERE level_num < ?)
SELECT n FROM t
Run Code Online (Sandbox Code Playgroud)

但是,使用 HSQLDB 2.4.0 我得到以下异常

java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: T
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.JDBCStatement.executeQuery(Unknown Source)
    ... 
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: T
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.ParserDQL.readTableName(Unknown Source)
    at org.hsqldb.ParserDQL.readTableOrSubquery(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableReference(Unknown Source)
    at org.hsqldb.ParserDQL.XreadFromClause(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableExpression(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQuerySpecification(Unknown Source)
    at org.hsqldb.ParserDQL.XreadSimpleTable(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryPrimary(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryTerm(Unknown Source)
    at org.hsqldb.ParserDQL.XreadSetOperation(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpressionBody(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpression(Unknown Source)
    at org.hsqldb.ParserDQL.XreadSubqueryTableBody(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableNamedSubqueryBody(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpression(Unknown Source)
    at org.hsqldb.ParserDQL.compileCursorSpecification(Unknown Source)
    at org.hsqldb.ParserCommand.compilePart(Unknown Source)
    at org.hsqldb.ParserCommand.compileStatements(Unknown Source)
    at org.hsqldb.Session.executeDirectStatement(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 37 more
Run Code Online (Sandbox Code Playgroud)

UNNEST这个特定的用例也可以通过和的组合来解决SEQUENCE_ARRAY,但我想避免引入 HSQLDB 特定的代码路径。

Vla*_*nov 2

我将从最简单的递归查询形式开始,不使用序列并使用硬编码限制,然后逐渐向其中添加额外的位。

根据With Clause and Recursive Queries文档中的示例,语法应如下所示:

WITH RECURSIVE
t(level_num)
AS
(
    VALUES(1)

    UNION ALL

    SELECT
        level_num + 1
    FROM t
    WHERE level_num < 10
)
SELECT level_num 
FROM t
;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,文档说:

HyperSQL 将递归限制为 265 轮。如果超过此值,则会引发错误。

我会尝试最简单的查询,如上面的查询,确保它有效,然后尝试使用,例如,而1000不是10,看看它返回什么错误。如果它与您最初遇到的错误相同,那么您就找到了原因。


附注:对于此类任务,我将使用永久的数字表,而不是动态递归地生成它们。我们的系统中有一个包含 100K 数字的表。它很简单并且可以在任何 DBMS 中工作。填充一次并根据需要使用。我知道在 SQL Server 中,递归查询速度明显较慢(在此类任务中),但我不了解 HyperSQL。此外,递归深度限制为 265 是相当严格的。最有可能的是,由于递归深度的限制如此之低,因此不可能检测到性能上的任何差异。但是,265 个数字是否足以满足您的目的?