0

I am following official tutorial of doobie.

Here is my code:

import doobie._
import doobie.implicits._
import doobie.util.ExecutionContexts
import cats._
import cats.data._
import cats.effect.IO
import cats.implicits._

// We need a ContextShift[IO] before we can construct a Transactor[IO]. The passed ExecutionContext
// is where nonblocking operations will be executed. For testing here we're using a synchronous EC.
implicit val cs = IO.contextShift(ExecutionContexts.synchronous)

// A transactor that gets connections from java.sql.DriverManager and executes blocking operations
// on an our synchronous EC. See the chapter on connection handling for more info.
val xa = Transactor.fromDriverManager[IO](
  "org.postgresql.Driver",     // driver classname
  "jdbc:postgresql:world",     // connect URL (driver-specific)
  "postgres",                  // user
  "",                          // password
  ExecutionContexts.synchronous // just for testing
)

val y = xa.yolo
import y._


val drop =
  sql"""
    DROP TABLE IF EXISTS person
  """.update.run

val create =
  sql"""
    CREATE TABLE person (
      id   SERIAL,
      name VARCHAR NOT NULL UNIQUE,
      age  SMALLINT
    )
  """.update.run

Then I run and create tables: (drop, create).mapN(_ + _).transact(xa).unsafeRunSync

Everything from above works and is as in official docs.

Here is my own code that goes afterwards:

val first: String = "(1, 'John', 31)" 
val second: String = "(2, 'Alice', 32)"

sql"""insert into person (id, name, age) VALUES $first, $second""".update.quick.unsafeRunSync

I also tried:

sql"""insert into person (id, name, age) VALUES $first, $second""".update.run.transact(xa).unsafeRunSync

However they both give me:

org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"

How to pass dynamically multiple(there might be more than 2) values in INSERT INTO?

techkuz
  • 3,608
  • 5
  • 34
  • 62

1 Answers1

0

You can use the batch update, as described in the doc:

type PersonInfo = (Int, String, Int)

def insertMany(ps: List[PersonInfo]): ConnectionIO[Int] = {
  val sql = "insert into person (id, name, age) values (?, ?, ?)"
  Update[PersonInfo](sql).updateMany(ps)
}

// Some rows to insert
val data = List[PersonInfo](
  (1,"John", 31),
  (2,"Alice", 32)
)

// To use `quick` see doc https://tpolecat.github.io/doobie/docs/07-Updating.html#setting-up
insertMany(data).quick.unsafeRunSync

// or
insertMany(data).transact(xa) // where `xa` is your `Transactor`
Valy Dia
  • 2,781
  • 2
  • 12
  • 32
  • ```error: value quick is not a member of doobie.ConnectionIO[Int] insertMany(data).quick.unsafeRunSync``` – techkuz Jul 15 '19 at 08:36
  • 2
    The `quick` comes from the `yolo` mode defined at the top of the doc https://tpolecat.github.io/doobie/docs/07-Updating.html#setting-up - which is handy to run through the examples - otherwise you can use `transact` on the resulting `Connection` – Valy Dia Jul 15 '19 at 09:13