You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle JDBC预编译语句抛出ORA-00905缺失关键字异常求助

问题原因分析

这个ORA-00905错误的核心原因是你在PreparedStatement的SQL语句里错误地将Oracle的timestamp关键字和占位符?绑定在一起了。

直接执行硬编码语句时,timestamp '2021-07-07 00:00:00'是Oracle合法的时间字面量语法——关键字timestamp和后面的字符串值是一个整体,数据库能正确解析。但用PreparedStatement时,占位符?的作用是替换单个参数值,而不是替换字面量的一部分。当驱动把timestamp ?发送给数据库时,数据库会认为timestamp后面应该跟具体的字符串值,而不是占位符,因此抛出“缺少关键字”的错误。

解决方法

你只需要两步就能修复这个问题:

1. 修改SQL语句,移除timestamp关键字

把原SQL中的created_at BETWEEN timestamp ? AND timestamp ?改成:

SELECT COUNT(*) as count FROM my_table WHERE product_id = ? AND status = ? AND created_at BETWEEN ? AND ? ;

2. 使用JDBC的setTimestamp()方法传入时间参数

在Java代码中,将你的时间值转换为java.sql.Timestamp类型,然后通过PreparedStatement.setTimestamp()方法设置参数,示例代码如下:

// 假设你已经获取了数据库连接connection
String sql = "SELECT COUNT(*) as count FROM my_table WHERE product_id = ? AND status = ? AND created_at BETWEEN ? AND ?";

try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
    // 设置字符串参数
    pstmt.setString(1, "TEST");
    pstmt.setString(2, "SUCCESS");
    
    // 设置时间参数(示例:构造开始和结束时间)
    Timestamp startTime = Timestamp.valueOf("2021-07-07 00:00:00");
    Timestamp endTime = Timestamp.valueOf("2021-07-07 23:59:59");
    pstmt.setTimestamp(3, startTime);
    pstmt.setTimestamp(4, endTime);
    
    // 执行查询并处理结果
    ResultSet rs = pstmt.executeQuery();
    if (rs.next()) {
        int count = rs.getInt("count");
        System.out.println("匹配的记录数:" + count);
    }
} catch (SQLException e) {
    e.printStackTrace();
}

补充说明

JDBC驱动会自动将java.sql.Timestamp类型的参数转换为Oracle数据库能识别的时间格式,完全不需要在SQL中手动添加timestamp关键字。这种方式不仅解决了语法错误,还符合PreparedStatement参数化查询的最佳实践,能有效避免SQL注入风险。

内容的提问来源于stack exchange,提问作者Yaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 21:12:42