Scala Doob ie PSQLException: ОШИБКА: синтаксическая ошибка в конце ввода при использовании «Like%» - PullRequest
2 голосов
/ 26 января 2020

Я использую PostgreSQL 12.1 с Scala и Doob ie. Получение исключения при попытке выполнить запрос с синтаксисом LIKE%. Работает без%.

Мой код:

implicit val cs = IO.contextShift(ExecutionContexts.synchronous)

val driver = "org.postgresql.Driver"
val connectionString = "jdbc:postgresql:postgres"
val user = "postgres"
val pass = "P@ssw0rd"

lazy val xa = Transactor.fromDriverManager[IO](driver, connectionString, user, pass)

def findNamePref(title: String): Option[Book] = {
    val s = sql"SELECT * FROM books WHERE title LIKE $title%".query[Book].option
    s.transact(xa).unsafeRunSync()
}

Исключение:

Исключение в потоке "главная" организация. postgresql .util.PSQLException: ОШИБКА: синтаксическая ошибка в конце ввода Позиция: 41 в орг. postgresql .core.v3.QueryExecutorImpl.receiveErrorResponse (QueryExecutorImpl. java: 2505) в орг. postgresql .core.v3.QueryExecutorImpl.processResults Quest ( . java: 2241) в орг. postgresql .core.v3.QueryExecutorImpl.execute (QueryExecutorImpl. java: 310) в орг. postgresql .jdb c .PgStatement.executeInternal (PgStatement. java: 447) в орг. postgresql .jdb c .PgStatement.execute (PgStatement. java: 368) в орг. postgresql .jdb c .PgPreparedStatement.executeWithFlags (PgPreparedStatement. java: 158) at or. 956) в doob ie .free.KleisliInterpreter. $ Anonfun $ примитив $ 2 (kleisliinterpreter. scala: 112) в cats.e ffect.internals.IORunLoop $ .cats $ effect $ innerals $ IORunLoop $$ l oop (IORunL oop. scala: 87) в cats.effect.internals.IORunLoop $ .startCancelable (IORunL oop. *) 1044 *: 41) в cats.effect.internals.IOBracket $ BracketStart.run (IOBracket. scala: 86) в cats.effect.internals.Trampoline.cats $ effect $ innerals $ Батут $$ instantL oop (Батут . scala: 70) в cats.effect.internals.Trampoline.startL oop (батут. scala: 36) в cats.effect.internals.TrampolineEC $ JVMTrampoline.super $ startL oop (батут E * 1051) *. scala: 93) at cats.effect.internals.TrampolineEC $ JVMTrampoline. $ Anonfun $ startLoop $ 1 (TrampolineE C. scala: 93) при scala .runtime.java8.JFunction0 $ mcV $ sp .apply (JFunction0 $ mcV $ sp. scala: 18) в scala .concurrent.BlockContext $ .withBlockContext (BlockContext. scala: 94) в cats.effect.internals.TrampolineEC $ JVMTrampoline.startL oop (Батут E C. scala: 93) на cats.effect.internals.Trampoline.execute (Батут. scala: 43) на cats.effect.internals.TrampolineE C .execute (Батут E * 1 064 *. scala: 44) в cats.effect.internals.IOBracket $ BracketStart.apply (IOBracket. scala: 72) в cats.effect.internals.IOBracket $ BracketStart.apply (IOBracket. scala: 52 ) в cats.effect.internals.IORunLoop $ .cats $ effect $ innerals $ IORunLoop $$ l oop (IORunL oop. scala: 136) в cats.effect.internals.IORunLoop $ RestartCallback.signal (IORunL oop. scala: 355) в cats.effect.internals.IORunLoop $ RestartCallback.apply (IORunL oop. scala: 376) в cats.effect.internals.IORunLoop $ RestartCallback.apply (IORunL oop. scala: 316) в cats.effect.internals.IOShift $ Tick.run (IOShift. scala: 36) в java .base / java .util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor. java: 1128) в java .base / java .util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor. java: 628) в java .base / java .lang.Thread. run (Thread. java: 834)

Зависимости:

scalaVersion := "2.13.1"


lazy val doobieVersion = "0.8.8"

libraryDependencies ++= Seq(
  "org.tpolecat" %% "doobie-core"     % doobieVersion,
  "org.tpolecat" %% "doobie-postgres" % doobieVersion,
  "org.tpolecat" %% "doobie-specs2"   % doobieVersion
)

Ответы [ 4 ]

2 голосов
/ 26 января 2020

Код заменит содержимое $title значением из параметра функции.

Однако запрос содержит % после параметра. После замены на значение SQL будет выглядеть как ... WHERE title LIKE 'myTitle'%, что недопустимо.

Вы можете объединить % с указанным параметром

val s = sql"SELECT * FROM books WHERE title LIKE $title || '%'".query[Book].option

, который переведет до ... WHERE title LIKE 'myTitle' || '%', затем до ... WHERE title LIKE 'myTitle%'

1 голос
/ 26 января 2020

Причина, по которой вы получили эту ошибку, заключается в том, что вы вписали строковую переменную в саму строку, т.е. заголовок в вашем случае. При использовании строковые переменные подставляются в его значение, поэтому вписывание строкового значения в двойные кавычки снова является синтаксической ошибкой. Таким образом, вы должны явно использовать заголовок путем объединения значения заголовка со строкой запроса select.

    "select * from.... Where title like %" 
   +title+"%" ;
1 голос
/ 26 января 2020

почему описано уже JGH .

Простым решением было бы добавить % к параметру.

Запрос:

val s = sql"SELECT * FROM books WHERE title LIKE $title".query[Book].option

Примеры:

findNamePref("Title")
findNamePref("Tit%")
findNamePref("%itle")
findNamePref("%")
0 голосов
/ 26 января 2020

Спасибо всем. Это то, что я использую в конце концов:

sql"SELECT * FROM books WHERE title LIKE ${title+"%"}".query[Book].option
...