Quill - INSERT INTO SELECT ... синтаксис? - PullRequest
0 голосов
/ 03 ноября 2018

Так что я недавно перешел из ScalikeJDBC в Quill в своем проекте scala из-за поддержки асинхронности.

Поддерживается ли какой-либо синтаксис SQL, как в приведенных ниже примерах?

INSERT INTO People (id, cityID)
SELECT 52, Cities.id
FROM Cities
WHERE Cities.name = 'New York City';

INSERT INTO State (id, numCities)
SELECT 4, COUNT(*)
FROM  Cities
WHERE Cities.state = 'NY'

Ожидаемое поведение

Я бы попробовал такие вещи, как

quote {
   for {
      count <- query[City].filter(_.state == 'NY').size
   } yield query[State].insert(lift(State(4, count))
}

quote {
   query[City].filter(_.state == 'NY').size.nested.insert(count => lift(State(4, count))
}

Но выдает такие ошибки, как:

  • "Карта значений не является членом Long" относительно ".size"
  • "nested не является членом Long" относительно ".size"

Конечно, если я делаю что-то вроде ниже, я получаю кучу ошибок:

quote {
   for {
      count <- List(query[City].filter(_.state == 'NY').size)
   } yield query[State].insert(lift(State(4, count))
}

Обход

В настоящее время кажется, что единственным обходным решением является выполнение двух отдельных запросов (один для получения количества и второй для вставки). Однако я думаю, что это станет неэффективным, если я буду делать много вставок на основе выбора.

с необработанными запросами

Я пробовал альтернативы с использованием инфикса, такие как:

quote {
    infix"""
      INSERT INTO Languages (id,iso639_1,name)
      VALUES (
        (SELECT x2.id + 1
        FROM (SELECT id FROM Languages UNION SELECT 0) x2
        LEFT JOIN Languages x1 ON (x2.id + 1) = x1.id
        WHERE x1.id IS NULL LIMIT 1),
        'Hello',
        'World'
      );
    """.as[?]
}

Но он продолжает выдавать следующие ошибки:

[error] (run-main-4a) com.github.mauricio.async.db.mysql.exceptions.MySQLException: Error 1064 - #42000 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO Languages (id,iso639_1,name)
[error]       VALUES (
[error]         (SELECT x2.id ' at line 2
[error] com.github.mauricio.async.db.mysql.exceptions.MySQLException: Error 1064 - #42000 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO Languages (id,iso639_1,name)
[error]       VALUES (
[error]         (SELECT x2.id ' at line 2

Что не соответствует действительности, так как я скопировал, вставил необработанный SQL в браузер sql, и он отлично работал.

1 Ответ

0 голосов
/ 03 ноября 2018
  final case class TestTable(id: Long, name: String)

  final val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal)

  import ctx._

  final val table  = quote(query[TestTable])
  final val size   = quote(table.filter(_.name == "hello world").size)
  //the insert action
  final val insert = quote {
    (e: TestTable) => table.insert(e)
  }

// тест

//INSERT INTO TestTable (id,name) VALUES ((SELECT COUNT(*) FROM TestTable x1 WHERE x1.name = 'hello world'), '')
ctx.run(insert(TestTable(size, "")))
...