使用HSQLDB生成基于CTE的序列

我使用递归公用表表达式来获取一批序列号.以下查询适用于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

但是对于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

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

最佳答案 我将从最简单的递归查询开始,不使用序列和硬编码限制,然后逐渐添加额外的位.

根据文档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
;

顺便说一句,文档说:

HyperSQL limits recursion to 265 rounds. If this is exceeded, an error
is raised.

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

旁注:我会使用永久数字表而不是为了这类任务递归生成它们.我们的系统中有一个包含100K数字的表.它很简单,适用于任何DBMS.填充一次并根据需要使用.我知道在SQL Server中递归查询明显较慢(在这种任务中),但我不知道HyperSQL.此外,递归深度限制为265只相当苛刻.最有可能的是,对递归深度的这种低限制,将无法检测到性能上的任何差异.但是,再次,265个数字足以满足您的目的吗?

点赞