【问题标题】:How do I insert Postgres "infinity" into a Timestamp field with JOOQ?如何使用 JOOQ 将 Postgres“infinity”插入时间戳字段?
【发布时间】:2018-01-15 13:58:32
【问题描述】:

我有一个这样定义的列:

expiry timestamp(0) without time zone not null

使用 Postgres,我可以发出如下 SQL:

insert into my_table(expiry) values ('infinity')

我一直在研究 JOOQ doco,但找不到任何处理此问题的示例。 我可以用 JOOQ 做到这一点吗?它会是什么样子?

另外,是否可以使用UpdatableRecord?我可以使用某种Timestamp 的无限“标志”实例吗?

【问题讨论】:

    标签: postgresql jooq sql-timestamp


    【解决方案1】:

    好的,找到了直接做的方法。

    MyRecord r = db.insertInto(
      MY_RECORD, 
      MY_RECORD.ID,
      MY_RECORD.CREATED,
      MY_RECORD.EXPIRY
    ).values(
      val(id),
      currentTimestamp(),
      val("infinity").cast(Timestamp.class)
    ).returning().fetchOne();
    

    但这感觉更像是一种解决方法,而不是正确的方法。将字符串转换为timestamp 对我来说似乎有点绕,所以我写了一个CustomField 以使其使用和查询更容易:

    public class TimestampLiteral extends CustomField<Timestamp> {
      public static final TimestampLiteral INFINITY = 
        new TimestampLiteral("'infinity'");
      public static final TimestampLiteral NEGATIVE_INFINITY = 
        new TimestampLiteral("'-infinity'");
      public static final TimestampLiteral TODAY = 
        new TimestampLiteral("'today'");
    
      private String literalValue;
    
      public TimestampLiteral(String literalValue){
        super("timestamp_literal", SQLDataType.TIMESTAMP);
        this.literalValue = literalValue;
      }
    
      @Override
      public void accept(Context<?> context){
        context.visit(delegate(context.configuration()));
      }
    
      private QueryPart delegate(Configuration configuration){
        switch( configuration.dialect().family() ){
          case POSTGRES:
            return DSL.field(literalValue);
    
          default:
            throw new UnsupportedOperationException(
              "Dialect not supported because I don't know how/if this works in other databases.");
        }
      }
    
    }
    

    那么查询是:

    MyRecord r = db.insertInto(
      MY_RECORD, 
      MY_RECORD.ID,
      MY_RECORD.CREATED,
      MY_RECORD.EXPIRY
    ).values(
      val(id),
      TimestampLiteral.TODAY,
      TimestampLiteral.INFINITY
    ).returning().fetchOne();
    

    不知道这是否一定是执行此操作的“正确”方式,但目前似乎可行。

    仍然很想知道是否有办法通过UpdatableRecord 做到这一点。

    【讨论】:

      【解决方案2】:

      我创建了一个java.sql.Timestamp,将org.postgresql.PGStatement.DATE_POSITIVE_INFINITY 传递给它的构造函数。

      create.insertInto(
        MY_RECORD, 
        MY_RECORD.ID,
        MY_RECORD.CREATED,
        MY_RECORD.EXPIRY
      ).values(
        1,
        new Timestamp(System.currentTimeMillis()),
        new Timestamp(PGStatement.DATE_POSITIVE_INFINITY)
      ).execute();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-07
        • 1970-01-01
        • 2011-09-05
        • 1970-01-01
        • 1970-01-01
        • 2021-08-01
        相关资源
        最近更新 更多