JPQL使用TO_DATE报错:识别变量'TO_DATE'未在FROM子句中定义
报错原因
你遇到的报错由3个核心问题共同导致:
@NamedQuery默认写的是JPQL(Java持久化查询语言),不是数据库原生SQL,JPQL本身没有内置TO_DATE函数,这个是数据库专属的原生函数,直接写会被JPQL识别为未定义变量- 参数占位符
:fechaactual不需要额外加单引号包裹,你加了单引号后会把参数名识别为普通字符串,无法正常注入参数 - 第二行日期过滤条件出现了
TO_DATE嵌套错误,相当于试图把TO_DATE(:fechaactual, 'YYYY-MM-DD')这个字符串再转成日期,属于语法错误
解决方案
最优方案:直接传入日期类型参数(无需转换)
JPA本身支持日期类型参数自动映射,你直接把入参fechaactual的类型设置为LocalDate(JDK8+)或者java.util.Date,查询语句里不需要加任何转换函数,修正后的代码如下:
@NamedQuery(name = "MvTarifa.obtenerTarifaPorCc", query = "SELECT m FROM MvTarifa m " + "INNER JOIN m.maTarifero t " + "INNER JOIN m.listaMvCtacteTariferos ct " + "WHERE m.tarffechainivigen <= :fechaactual " + "AND m.tarffechafinvigen > :fechaactual " + "AND t.tarffechainivigen <= :fechaactual " + "AND t.tarffechafinvigen > :fechaactual " + "AND ct.cttafechainivigen <= :fechaactual " + "AND ct.cttafechafinvigen >= :fechaactual " + "AND ct.ctactenumero = :numeroCuentaCorriente " + "AND m.ccorcodigo = :tarifaAsociadaCtaCte " + "AND t.tarimeson = :tarifaAsociadaMeson " + "AND t.emprcodigo = :codigoEmpresa " + "AND ct.emprcodigo = :codigoEmpresa " + "AND m.tarfversion > 0"),
调用查询时直接传入日期类型的参数即可,不需要手动转字符串。
方案2:JPQL调用原生函数
如果确实需要传入字符串格式的日期参数,必须用JPQL的FUNCTION关键字包裹原生函数调用,修正写法如下:
@NamedQuery(name = "MvTarifa.obtenerTarifaPorCc", query = "SELECT m FROM MvTarifa m " + "INNER JOIN m.maTarifero t " + "INNER JOIN m.listaMvCtacteTariferos ct " + "WHERE m.tarffechainivigen <= FUNCTION('TO_DATE', :fechaactual, 'YYYY-MM-DD') " + "AND m.tarffechafinvigen > FUNCTION('TO_DATE', :fechaactual, 'YYYY-MM-DD') " + "AND t.tarffechainivigen <= FUNCTION('TO_DATE', :fechaactual, 'YYYY-MM-DD') " + "AND t.tarffechafinvigen > FUNCTION('TO_DATE', :fechaactual, 'YYYY-MM-DD') " + "AND ct.cttafechainivigen <= FUNCTION('TO_DATE', :fechaactual, 'YYYY-MM-DD') " + "AND ct.cttafechafinvigen >= FUNCTION('TO_DATE', :fechaactual, 'YYYY-MM-DD') " + "AND ct.ctactenumero = :numeroCuentaCorriente " + "AND m.ccorcodigo = :tarifaAsociadaCtaCte " + "AND t.tarimeson = :tarifaAsociadaMeson " + "AND t.emprcodigo = :codigoEmpresa " + "AND ct.emprcodigo = :codigoEmpresa " + "AND m.tarfversion > 0"),
方案3:改用原生SQL查询
如果要直接使用原生SQL语法,把@NamedQuery换成@NamedNativeQuery,指定返回的实体类即可直接写TO_DATE函数。
内容的提问来源于stack exchange,提问作者Víctor Eduardo Duque Rosales
相关产品推荐
相关产品推荐

