无法识别 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 数据库的语法问题的主要内容,如果未能解决你的问题,请参考以下文章
ADO 无法识别旧式 SQL 连接。不知道如何在此特定查询中使用新式语法
Webpack 无法在我的 js 文件中识别我的 JSX 语法