如何使用scala向postgres插入间隔值

问题描述 投票:0回答:1

我正在使用下面的代码将数据插入 postgres 表的间隔数据类型,但出现一些错误。

var tm1 =  LocalDateTime.now()
var tm2 =  LocalDateTime.now()

var milliseconds = tm1.until(tm2, ChronoUnit.MILLIS)

var seconds = (milliseconds / 1000) % 60
var minutes = (milliseconds / (1000*60)) % 60
var hours   = (milliseconds / (1000*60*60)) % 24
var milisec = milliseconds - ((seconds * 1000) + (minutes * 60 * 1000) + (hours * 60 *60 * 1000))

var secondsNew = if (seconds.toString().length() == 1) "0" + seconds else seconds
var minutesNew = if (minutes.toString().length() == 1) "0" + minutes else minutes
var hoursNew = if (hours.toString().length() == 1) "0" + hours else hours
var milisecNew = if (milisec.toString().length() == 1) milisec + "00"  else if (milisec.toString().length() == 2)  milisec + "0" else milisec

var timeString = "%s:%s:%s".format(hoursNew, minutesNew, secondsNew)
var duration = LocalTime.parse(timeString)

var tm = Time.valueOf(DateTimeFormatter.ofPattern("HH:mm:ss").format(duration))

==> insertion

sql = "INSERT into etl.mls_refresh_snapshot(job_name,job_type,job_frequency,
source_table_name,source_count,target_count,job_run_duration,started_at,ended_at) VALUES(?,?,?,?,?,?::interval,?,?)"

var statement : PreparedStatement = conn.prepareStatement(sql)
statement.setTime(6,Time.valueOf(DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(duration)))
.......
Error :: java.lang.NumberFormatException: For input string: "18.000"

如果我将格式更改为毫秒=>

var timeString = "%s:%s:%s.%s".format(hoursNew, minutesNew, secondsNew, milisecNew)
var duration = LocalTime.parse(timeString)
var tm = Time.valueOf(DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(duration))

I am getting ERROR: invalid input syntax for type interval: "00:02:07+05:30"

请帮我解决这个问题!!!

java postgresql scala jdbc
1个回答
0
投票

似乎您正在使用 JDBC,但没有任何库。如果是这种情况,postgresql JDBC 驱动程序具有类 PGInterval

代替

setTime
,您必须使用
setObject
并传递
PGInterval
的实例作为参数。根据你的例子,你应该写一些类似的东西

val sql = "INSERT into etl.mls_refresh_snapshot(job_name, job_type, job_frequency, source_table_name, source_count, target_count, job_run_duration, started_at, ended_at)"

val statement : PreparedStatement = conn.prepareStatement(sql)

val pgInterval = new PGInterval(1,1,1,1,1,1,1)
statement.setObject(6, pgInterval)

如果您需要选择并获取该列的值,则必须执行以下操作

val result = statement.executeQuery("SELECT job_name, job_type, job_frequency, source_table_name, source_count, target_count, job_run_duration, started_at, ended_at FROM etl.mls_refresh_snapshot")
result.next()
val interval: PGInterval = result.getObject(6, classOf[PGInterval])

这里有基本但完整的示例,说明如何创建表、插入间隔值并从表中获取它

  • build.sbt
libraryDependencies ++= Seq(
  "com.dimafeng" %% "testcontainers-scala-scalatest" % "0.41.0" % Test,
  "com.dimafeng" %% "testcontainers-scala-postgresql" % "0.41.0" % Test,
  "org.postgresql" % "postgresql" % "42.5.4"
)
  • src/test/scala/PostgresqlContainerTest.scala
import com.dimafeng.testcontainers.PostgreSQLContainer
import com.dimafeng.testcontainers.scalatest.TestContainerForAll
import org.postgresql.util.PGInterval
import org.scalatest.funsuite.AsyncFunSuite
import org.scalatest.matchers.should.Matchers
import org.testcontainers.utility.DockerImageName

import java.sql.{DriverManager, PreparedStatement, Statement}

class PostgresqlContainerTest
    extends AsyncFunSuite
    with Matchers
    with TestContainerForAll {

  override val containerDef =
    PostgreSQLContainer.Def(DockerImageName.parse("postgres:15.4-alpine3.18"))

  test("CRUD for interval type column") {
    withContainers { pgContainer =>
      // load driver
      Class.forName(pgContainer.driverClassName)

      // connect
      val connection = DriverManager.getConnection(
        pgContainer.jdbcUrl,
        pgContainer.username,
        pgContainer.password
      )

      // create table with interval column
      val stmt: Statement = connection.createStatement
      val sql = "CREATE TABLE interval_table (interval_column Interval)"
      stmt.executeUpdate(sql)

      val years = 1
      val months = 4
      val days = 3
      val hours = 3
      val minutes = 22
      val seconds = 42

      // create the PGInterval object
      val pgInterval: PGInterval =
        new PGInterval(years, months, days, hours, minutes, seconds)

      // insert into table with interval value
      val preparedStatement: PreparedStatement = connection.prepareStatement(
        "INSERT INTO interval_table(interval_column) VALUES (?)"
      )

      // set the value using `setObject` and using `PGInterval` as parameter
      preparedStatement.setObject(1, pgInterval)
      preparedStatement.executeUpdate()

      // query the record saved before
      val select = connection.createStatement()
      val result =
        select.executeQuery("SELECT interval_column FROM interval_table")
      result.next()

      // get the interval value from the column
      val interval: PGInterval = result.getObject(1, classOf[PGInterval])

      // assert the expected values
      interval.getYears should be(years)
      interval.getMonths should be(months)
      interval.getDays should be(days)
      interval.getHours should be(hours)
      interval.getMinutes should be(minutes)
      interval.getSeconds should be(seconds)
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.