如何在预准备语句中传递带有''(timestamp)的字符串?

时间:2012-12-03 23:34:02

标签: postgresql syntax-error insert-update timestamp-with-timezone

我正在尝试执行以下查询

INSERT INTO hotspot(timestamp) VALUES 
(timestamp with time zone '2012-10-25 14:00:00 +05:00' at time zone 'EET');

我希望将时间戳作为变量传递。

我的时间戳列是带时区的时间戳类型。

你知道如何做到这一点吗?

当我这样做...(Java,Postgresql)

    String stm= "INSERT INTO hotspot(timestamp) VALUES(timestamp with time zone ? at time zone 'EET')";
    pst = con.prepareStatement(stm);
    pst.setString(1, "2012-08-24 14:00:00 +05:00");
    pst.executeUpdate();

我在“$ 1”或附近收到语法错误

无论如何我能克服这个错误吗? 提前谢谢!!

更新: 我尝试通过以下方式使用setTimestamp ......

Calendar c=Calendar.getInstance(TimeZone.getTimeZone("GMT+05:00"));
String stm= "INSERT INTO hotspot(timestamp) VALUES(?)";
pst = con.prepareStatement(stm);
pst.setTimestamp(1,Timestamp.valueOf("2012-01-05 14:00:00"), c );
pst.executeUpdate();

我认为数据库中的正确值应该是(关于我的本地时区是EET(+02))

2012-01-05 11:00:00 +02

但是使用pgadmin我检查值,我得到

2012-01-05 14:00:00 +02

有什么建议吗?

2 个答案:

答案 0 :(得分:6)

考虑使用 setTimestamp()方法而不是 setString()方法。检查this link以了解如何使用 PreparedStatement

编辑:正如我在评论中所解释的那样,使用三个参数检查API reference的setTimestamp():

  

将指定参数设置为给定的java.sql.Timestamp值,   使用给定的Calendar对象。驱动程序使用Calendar对象   构造一个SQL TIMESTAMP值,驱动程序然后发送该值   数据库。使用Calendar对象,驱动程序可以计算   时间戳考虑到自定义时区。如果没有Calendar对象   如果指定,则驱动程序使用默认时区,即时区   运行应用程序的虚拟机。

答案 1 :(得分:4)

Federico Cristina非常正确setTimestamp是正确的做法。

语法错误的原因是您在传递参数时无法使用前导类型说明符指定类型。 INTEGER '4'样式仅对文字有效,而非参数。

您的代码将在协议级别PREPARE d然后EXECUTE d。如果我PREPARE它会发生什么:

regress=> PREPARE blah(timestamptz) AS INSERT INTO hotspot(timestamp) VALUES(timestamp with time zone $1 at time zone 'EET');
ERROR:  syntax error at or near "$1"
LINE 1: ...otspot(timestamp) VALUES(timestamp with time zone $1 at time...

由于在查询参数中指定了数据类型,因此可以省略它,而是编写:

String stm= "INSERT INTO hotspot(\"timestamp\") VALUES(? at time zone 'EET')";

请注意,我也引用了"timestamp",因为它是一个保留字。它在某些情况下不会引用但在其他情况下不会引用。选择数据类型名称或保留字作为列名通常是一个坏主意。