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

Java向PostgreSQL插入Date类型数据报错:列类型不匹配

向PostgreSQL的autore表插入date类型字段失败的解决方法

问题现象

向PostgreSQL的autore表插入记录时,datanascita(date类型)列插入失败,核心报错提示:

org.postgresql.util.PSQLException: ERROR: 列"datanascita"是date类型,但表达式是integer类型
提示: 你需要重写或转换表达式。
位置: 90

插入执行代码

Connection connection = DatabaseConnection.getInstance().getConnection();
ResultSet result = null;
try
{
    Statement statement = connection.createStatement();
    statement.executeUpdate(query,Statement.RETURN_GENERATED_KEYS);
    result = statement.getGeneratedKeys();
} catch (SQLException e)
{
    e.printStackTrace();
}
finally
{
    return result;
}

调用代码

String authorName = "Paul";
String authorSurname = "Mac";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd" ) ; 
LocalDate date = LocalDate.parse ( "2017-09-24" , f );

String query = "Insert into autore(nome_autore, cognome_autore, datanascita) values('"+authorName+"', '"+authorSurname+"', "+date+")";

完整报错栈

org.postgresql.util.PSQLException: ERROR: column "datanascita" is of type date but expression is of type integer
  Suggerimento: You will need to rewrite or cast the expression.
  Posizione: 90
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2366)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:356)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:413)
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:333)
    at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:319)
    at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:1259)
    at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:1240)
    at projectRiferimentiBibliografici/com.ProjectRiferimentiBibliografici.DatabaseConnection.QueryManager.executeUpdateWithResultSet(QueryManager.java:113)
    at projectRiferimentiBibliografici/com.ProjectRiferimentiBibliografici.DAOImplementation.AuthorDaoPostgresql.insertAuthor(AuthorDaoPostgresql.java:136)
    at projectRiferimentiBibliografici/com.ProjectRiferimentiBibliografici.Main.MainCe.main(MainCe.java:43)

问题原因

拼接SQL时,LocalDate对象直接拼接会生成2017-09-24格式的字符串,但因为没有包裹单引号,PostgreSQL会将其识别为2017-9-24的算术运算,结果为整数1984,与date类型的列不匹配,从而抛出类型错误。

解决方案

方法1:手动给日期加单引号(不推荐)

修改SQL拼接逻辑,给date变量添加单引号,让PostgreSQL识别为日期字符串:

String query = "Insert into autore(nome_autore, cognome_autore, datanascita) values('"+authorName+"', '"+authorSurname+"', '"+date+"')";

该方法仅临时解决问题,存在SQL注入风险,且日期格式不符合要求时仍会出错,不建议生产环境使用。

方法2:使用PreparedStatement(推荐)

采用预编译语句绑定参数,既能自动处理类型转换,又能彻底避免SQL注入:

修改插入执行代码

Connection connection = DatabaseConnection.getInstance().getConnection();
ResultSet result = null;
try (PreparedStatement pstmt = connection.prepareStatement(
    "Insert into autore(nome_autore, cognome_autore, datanascita) values(?, ?, ?)",
    Statement.RETURN_GENERATED_KEYS)) {
    
    pstmt.setString(1, authorName);
    pstmt.setString(2, authorSurname);
    // 两种参数绑定方式任选其一
    pstmt.setObject(3, date); // 直接绑定LocalDate,JDBC驱动自动转换
    // pstmt.setDate(3, java.sql.Date.valueOf(date)); // 转换为java.sql.Date绑定
    
    pstmt.executeUpdate();
    result = pstmt.getGeneratedKeys();
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    return result;
}

调用代码调整

无需手动拼接SQL,直接传入参数即可(yyyy-MM-dd是LocalDate.parse的默认格式,可省略格式化器):

String authorName = "Paul";
String authorSurname = "Mac";
LocalDate date = LocalDate.parse("2017-09-24");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:31:05