【问题标题】:Scala Doobie PSQLException: ERROR: syntax error at end of input when use "Like %"Scala Doobie PSQLException:错误:使用“Like %”时输入末尾的语法错误
【发布时间】:2020-01-26 09:24:09
【问题描述】:

我将 PostgreSQL 12.1 与 Scala 和 Doobie 一起使用。尝试使用 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()
}

例外:

线程“主”org.postgresql.util.PSQLException 中的异常:错误: 输入位置末尾的语法错误:41 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2505) 在 org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2241) 在 org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:310) 在 org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:447) 在 org.postgresql.jdbc.PgStatement.execute(PgStatement.java:368) 在 org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:158) 在 org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:108) 在 doobie.free.KleisliInterpreter$PreparedStatementInterpreter.$anonfun$executeQuery$2(kleisliinterpreter.scala:956) 在 doobie.free.KleisliInterpreter.$anonfun$primitive$2(kleisliinterpreter.scala:112) 在 猫.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:87) 在 猫.effect.internals.IORunLoop$.startCancelable(IORunLoop.scala:41) 在 cat.effect.internals.IOBracket$BracketStart.run(IOBracket.scala:86) 在 cat.effect.internals.Trampoline.cats$effect$internals$Trampoline$$immediateLoop(Trampoline.scala:70) 在cats.effect.internals.Trampoline.startLoop(Trampoline.scala:36) 在 cat.effect.internals.TrampolineEC$JVMTrampoline.super$startLoop(TrampolineEC.scala:93) 在 cat.effect.internals.TrampolineEC$JVMTrampoline.$anonfun$startLoop$1(TrampolineEC.scala:93) 在 scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18) 在 scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:94) 在 cat.effect.internals.TrampolineEC$JVMTrampoline.startLoop(TrampolineEC.scala:93) 在cats.effect.internals.Trampoline.execute(Trampoline.scala:43) 在 cat.effect.internals.TrampolineEC.execute(TrampolineEC.scala:44) 在 猫.effect.internals.IOBracket$BracketStart.apply(IOBracket.scala:72) 在 猫.effect.internals.IOBracket$BracketStart.apply(IOBracket.scala:52) 在 猫.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:136) 在 猫.effect.internals.IORunLoop$RestartCallback.signal(IORunLoop.scala:355) 在 猫.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.scala:376) 在 cat.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.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
)

【问题讨论】:

    标签: sql postgresql scala doobie


    【解决方案1】:

    代码会将$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%'

    【讨论】:

      【解决方案2】:

      为什么已经描述了JGH

      一个简单的解决方法是将% 添加到参数中。

      请求:

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

      例子:

      findNamePref("Title")
      findNamePref("Tit%")
      findNamePref("%itle")
      findNamePref("%")
      

      【讨论】:

        【解决方案3】:

        您收到此错误的原因是您在字符串本身中写入了一个字符串变量,即您的情况下的标题。在使用时,字符串变量被替换为它的值,因此在双引号内写一个字符串值又是一个语法错误。所以, 您应该通过将标题值连接到选择查询字符串来明确使用标题。

            "select * from.... Where title like %" 
           +title+"%" ;
        

        【讨论】:

          【解决方案4】:

          谢谢大家。毕竟这是我使用的:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-21
            • 2019-02-20
            • 2022-12-03
            • 2013-04-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多