2017-06-10 76 views
4

我正在使用遞歸公用表表達式來獲取一批序列號。以下查詢適用於Postgres,SQL Server和H2(減去VALUES部分)。基於CTE的HSQLDB序列生成

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 

這種特殊的使用案例也與UNNESTSEQUENCE_ARRAY的組合來解決,但我想,以避免引入一個HSQLDB特定的代碼路徑。

回答

1

我從遞歸查詢的最簡單形式開始,不使用序列和硬編碼限制,然後逐漸向其添加額外的位。

根據在文檔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限制遞歸265發子彈。如果超過此值,則會引發錯誤 。

我想嘗試最簡單的查詢,像一個以上,確保它的工作原理,然後用,說試試吧,1000代替10,看看是什麼錯誤時返回。如果它與你原來的錯誤是一樣的,那麼你找到了原因。


一個方面:我會使用一個數字永久表,而不是爲這種任務遞歸地生成它們。我們的系統中有一個包含100K數字的表格。這很簡單,可以在任何DBMS中工作。填充一次並根據需要使用。我知道在SQL Server中,遞歸查詢顯然比較慢(在這類任務中),但我並不瞭解HyperSQL。而且,遞歸深度限制到265也相當苛刻。最有可能的是,在遞歸深度上具有如此低的限制,將不可能檢測到任何性能差異。但是,265號碼足以滿足您的需求了嗎?

+0

如果我執行你的代碼,查詢不會返回,但會燒燬大量的CPU。查詢是否適合您? 我很好,265次遞歸限制,我不希望用戶使用超過100(他們,我知道)。這是「框架」的代碼,所以我不想強制給用戶一個數字表。 –

+0

對不起,我手邊沒有HSQLDB試試。我只看文檔就寫了。主要觀點仍然成立。我會盡量做出最簡單的遞歸查詢,然後逐個添加額外的位。如增加迭代次數,然後添加使用序列。 –

+0

我同意,我試過你的代碼,我沒有看到我可以如何簡化它,它沒有錯誤消息(只是刻錄CPU)失敗。所以我在這裏有點不知所措。 –