一尘不染

在H2上的NamedParameterJDBCTemplate上使用整数时,数据类型未知[SPRING-BOOT]

spring-boot

我正在使用带有H2的内存数据库测试Dao。我正在将一个int传递给带有地图的查询以执行它。该查询在Oracle SQL上运行正常,但在H2中未成功。

    @Override
public int deleteCancelled(int days) {
    final Map<String, Object> namedParameters = new HashMap<String, Object>();

    namedParameters.put(DAYS, days);
    namedParameters.put(STATUS, StatusEnum.CANCELLED.toString());

    int updated = this.namedParameterJdbcTemplate.update(Query.QUERIES.DELETE_CANCELLED, namedParameters);

    return updated;
}

查询

      public static final String DELETE_CANCELLED = "DELETE FROM MY_TABLE "
      + "WHERE UPDATE_TS < SYSDATE - :days AND STATUS = :status";

当我尝试在H2上执行此查询时,它返回:

错误

org.springframework.jdbc.UncategorizedSQLException: 
PreparedStatementCallback; uncategorized SQLException for SQL [DELETE FROM 
MY_TABLE WHERE UPDATE_TS < SYSDATE - ? AND STATUS = ?]; SQL state 
[HY004]; error code [50004]; Unknown data type : "?"
Unknown data type: "?"; SQL statement:
DELETE FROM MY_TABLE WHERE UPDATE_TS < SYSDATE - ? AND STATUS = ? 
[50004-196]; nested exception is org.h2.jdbc.JdbcSQLException: Unknown data 
type : "?"
Unknown data type: "?"; SQL statement:
DELETE FROM MY_TABLE WHERE UPDATE_TS < SYSDATE - ? AND STATUS = ? 
[50004-196]

我尝试执行对查询中的int进行硬编码的查询(SYSDATE =
4),并且可以正常工作,还尝试将原始int包装到Integer.valueOf(days)中,并使用MapSqlParameterSource指定哪种数据类型,但两者均无效。

为什么不起作用?有谁知道?提前致谢。

编辑:

状态枚举

public enum StatusEnum {

CANCELLED("Cancelled"), 
CONFIRMED("Confirmed"), 
PENDING("Pending"), 
SENT("Sent"),


private final String text;

/**
 * @param text
 */
private StatusEnum(final String text) {
    this.text = text;
}

/* (non-Javadoc)
 * @see java.lang.Enum#toString()
 */
@Override
public String toString() {
    return text;
}

}


阅读 480

收藏
2020-05-30

共1个答案

一尘不染

出现此异常似乎是因为H2试图在编译时对语句进行类型检查,并且无法唯一地确定参数的类型:它可以是日期,也可以是数字,或者其他。

解决方法(我提出GitHub问题中提供)是替换

SYSDATE - ?

SYSDATE - CAST(? AS INTEGER)

我已经检查了它,它在H2和Oracle上均可使用。

2020-05-30