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

JDBC从SQLite数据库获取日期报错:不存在'Date'列

解决SQLite存储UnixEpoch日期后JDBC提示"No such column exists 'Date'"的问题

首先,这个错误的核心指向很明确:你的EMPLOYEE_ACTIVITY表中不存在名为Date的列,或者你的查询语句引用了错误的列名。我们一步步来排查和解决:

1. 先确认建表语句是否正确创建了Date列

从你给出的代码片段来看,建表语句写到employeeID INTEGER NOT NULL,就截断了——如果这里没有后续的Date INTEGER NOT NULL,(或类似定义),那表本身就没有这个列,自然会报错。

正确的建表语句应该包含存储UnixEpoch时间戳的Date列(因为UnixEpoch是整数类型,所以列类型定义为INTEGER):

public void createActivityTable() {
    Statement stmt = null;
    try (Connection connection = connectionClass.connectToMainDb(true)) {
        stmt = connection.createStatement();
        String table = "CREATE TABLE IF NOT EXISTS EMPLOYEE_ACTIVITY (" +
                "ActivityIndex INTEGER PRIMARY KEY AUTOINCREMENT," +
                "employeeID INTEGER NOT NULL," +
                "Date INTEGER NOT NULL," + // 新增这一行,定义存储UnixEpoch的列
                // 其他字段继续补充...
                ")";
        stmt.executeUpdate(table);
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 别忘了关闭Statement
        try {
            if (stmt != null) stmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

⚠️ 注意:如果表已经创建过(因为用了IF NOT EXISTS),修改建表语句不会自动添加新列。你需要要么:

  • 删除旧表后重新运行建表代码,
  • 执行ALTER TABLE EMPLOYEE_ACTIVITY ADD COLUMN Date INTEGER NOT NULL;来添加列(如果允许非空的话,要确保已有数据能填充默认值,或者先设为允许NULL再补数据)。

2. 检查查询语句的列名是否正确

如果表结构里确实有Date列,那要检查你的JDBC查询代码里有没有拼写错误,或者不小心用了大小写敏感的引用:

  • SQLite默认列名不区分大小写,但如果你在查询里用了双引号(比如SELECT "date" FROM ...),就会严格匹配大小写,这时候如果列名是Date就会报错。
  • 确保查询语句里的列名和建表时的完全一致(比如不要把Date写成Dates或date_time)。

举个正确的查询示例:

// 用PreparedStatement更安全,避免SQL注入
String query = "SELECT ActivityIndex, employeeID, Date FROM EMPLOYEE_ACTIVITY WHERE employeeID = ?";
try (Connection conn = connectionClass.connectToMainDb(false);
     PreparedStatement pstmt = conn.prepareStatement(query)) {
    pstmt.setInt(1, targetEmployeeId);
    ResultSet rs = pstmt.executeQuery();
    
    while (rs.next()) {
        // 读取UnixEpoch时间戳(假设是秒级,若存的是毫秒则不用乘1000)
        long unixTimestamp = rs.getLong("Date");
        // 转换成Java Date对象
        java.util.Date activityDate = new java.util.Date(unixTimestamp * 1000);
        // 或者用Java 8+的时间API更推荐
        Instant instant = Instant.ofEpochSecond(unixTimestamp);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        
        // 处理你的业务逻辑...
        System.out.println("员工活动日期:" + localDateTime);
    }
} catch (SQLException e) {
    e.printStackTrace();
}

3. 额外技巧:让SQLite帮你转换日期格式

如果你需要直接拿到格式化后的日期字符串,可以在查询时用SQLite内置的datetime函数转换UnixEpoch:

SELECT ActivityIndex, employeeID, datetime(Date, 'unixepoch') AS formatted_date FROM EMPLOYEE_ACTIVITY

然后在JDBC中通过rs.getString("formatted_date")获取类似2024-05-20 14:30:00的字符串,再转换成Java日期类型。

快速验证表结构的方法

可以用SQLite命令行或可视化工具(比如DB Browser for SQLite)执行以下命令,查看表的所有列:

PRAGMA table_info(EMPLOYEE_ACTIVITY);

如果输出里没有Date列,就回到第一步补全建表语句。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:38:34