无法识别 H2 数据库的语法问题

Posted

技术标签:

【中文标题】无法识别 H2 数据库的语法问题【英文标题】:Unable to identify syntax issue with H2 database 【发布时间】:2021-08-29 07:47:12 【问题描述】:

查询:

SELECT
                cin,
                reviewDate,
                kycStatus
            FROM
                (
                    SELECT
                        ppc.prty_idnt_num  AS cin,
                        prty_sts_strt_dttm AS reviewDate,
                        prty_sts_cd        AS kycStatus,
                        ROW_NUMBER()
                        OVER(PARTITION BY ps.prty_id
                             ORDER BY
                                 prty_sts_strt_dttm DESC
                        ) AS rownum
                    FROM
                        public.party_status ps
                        LEFT JOIN public.party_position_current ppc ON ppc.prty_id = ps.prty_id
                    WHERE
                            UPPER(prty_sts_clsn_cd) = 'KYC'
                        AND ppc.prty_idnt_num = :cin
                ) kyc
             WHERE
                rownum = 1 OR rownum IS NULL;

错误:

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "SELECT    CIN,    REVIEWDATE,    KYCSTATUS FROM    (        SELECT            PPC.PRTY_IDNT_NUM  AS CIN,            PRTY_STS_STRT_DTTM AS REVIEWDATE,            PRTY_STS_CD        AS KYCSTATUS,            ROW_NUMBER() OVER(PARTITION BY PS.PRTY_ID                 ORDER BY PRTY_STS_STRT_DTTM DESC            ) AS ROWNUM[*]        FROM            PUBLIC.PARTY_STATUS PS            LEFT JOIN PUBLIC.PARTY_POSITION_CURRENT PPC ON PPC.PRTY_ID = PS.PRTY_ID        WHERE                UPPER(PRTY_STS_CLSN_CD) = 'KYC'            AND PPC.PRTY_IDNT_NUM = ?    ) KYC WHERE    ROWNUM = 1 OR ROWNUM IS NULL"; expected "identifier"; SQL statement:
SELECT    cin,    reviewDate,    kycStatus FROM    (        SELECT            ppc.prty_idnt_num  AS cin,            prty_sts_strt_dttm AS reviewDate,            prty_sts_cd        AS kycStatus,            ROW_NUMBER() OVER(PARTITION BY ps.prty_id                 ORDER BY prty_sts_strt_dttm DESC            ) AS rownum        FROM            PUBLIC.party_status ps            LEFT JOIN PUBLIC.party_position_current ppc ON ppc.prty_id = ps.prty_id        WHERE                UPPER(prty_sts_clsn_cd) = 'KYC'            AND ppc.prty_idnt_num = ?    ) kyc WHERE    rownum = 1 OR rownum IS NULL [42001-200]

查询在 DB (Teradata) 中运行良好,但在 H2(用作测试数据库)中失败。我无法弄清楚语法有什么问题。我怀疑row_number() 是罪魁祸首,但不确定。谁能帮忙解决这个问题?

【问题讨论】:

@TimBiegeleisen 添加了格式化查询 ppc.prty_idnt_num = :cin :cin是什么,H2是否支持命名参数? @TimBiegeleisen 是的,它确实如此。我已经在 h2 中使用命名参数测试了数百个查询,没有任何问题。 那个错误信息真的很模糊。我建议将您的查询分开并测试各个部分。首先尝试自己执行别名为kyc 的子查询。看看可能是什么错误。 【参考方案1】:

ROWNUM 是 H2 中的函数名。所以你不能直接使用ROWNUM。 您可以将ROWNUM 更改为任何其他变量,也可以像这样更改您的查询

SELECT
    cin,
    reviewDate,
    kycStatus,
    `ROWNUM`
FROM
    (
    SELECT
        ppc.prty_idnt_num AS cin,
        prty_sts_strt_dttm AS reviewDate,
        prty_sts_cd AS kycStatus
        ,
        ROW_NUMBER() OVER( PARTITION BY ps.prty_id ORDER BY prty_sts_strt_dttm DESC ) AS `ROWNUM`
    FROM
        public.party_status ps
    LEFT JOIN public.party_position_current ppc ON
        ppc.prty_id = ps.prty_id
    WHERE
        UPPER(prty_sts_clsn_cd) = 'KYC'
        AND 
        ppc.prty_idnt_num = 1
                ) kyc
WHERE
    `ROWNUM` = 1
    OR `ROWNUM` IS NULL;

【讨论】:

对不起,这没有帮助。我重命名了 rownum 别名并尝试将其放在引号中,但没有任何效果。我什至删除了整个 rownum 东西,但它仍然失败,所以我相信这是一个完全不同的问题。 我已经在 H2 数据库中执行了查询,并且它没有任何问题。异常还是一样吗? 你还是一样 我不知道发生了什么,但它现在工作正常。我重新运行了整个测试套件,唯一有效的是如果我将 rownum 别名放在单引号中,而不管我给别名取什么名字。想知道为什么它只抱怨 rownum 函数别名。 很遗憾,teradata 无法识别 ``` :(

以上是关于无法识别 H2 数据库的语法问题的主要内容,如果未能解决你的问题,请参考以下文章

在SEO检查中无法识别H1和H2标题。角

模板默认语法无法识别

ADO 无法识别旧式 SQL 连接。不知道如何在此特定查询中使用新式语法

Webpack 无法在我的 js 文件中识别我的 JSX 语法

xcode 无法识别 sencha touch javascript 语法

为啥 vue 在第一次编译时无法识别 TS 语法,但在第二次编译时可以正常工作?