Scala Doobie PSQLException: ERROR: syntax error at end of input when use "Like %"
Scala Doobie PSQLException: ERROR: syntax error at end of input when use "Like %"
我正在使用带有 Scala 和 Doobie 的 PostgreSQL 12.1。尝试使用 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()
}
异常:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR:
syntax error at end of input Position: 41 at
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2505)
at
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2241)
at
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:310)
at
org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:447)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:368) at
org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:158)
at
org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:108)
at
doobie.free.KleisliInterpreter$PreparedStatementInterpreter.$anonfun$executeQuery(kleisliinterpreter.scala:956)
at
doobie.free.KleisliInterpreter.$anonfun$primitive(kleisliinterpreter.scala:112)
at
cats.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:87)
at
cats.effect.internals.IORunLoop$.startCancelable(IORunLoop.scala:41)
at
cats.effect.internals.IOBracket$BracketStart.run(IOBracket.scala:86)
at
cats.effect.internals.Trampoline.cats$effect$internals$Trampoline$$immediateLoop(Trampoline.scala:70)
at cats.effect.internals.Trampoline.startLoop(Trampoline.scala:36)
at
cats.effect.internals.TrampolineEC$JVMTrampoline.super$startLoop(TrampolineEC.scala:93)
at
cats.effect.internals.TrampolineEC$JVMTrampoline.$anonfun$startLoop(TrampolineEC.scala:93)
at
scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
at
scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:94)
at
cats.effect.internals.TrampolineEC$JVMTrampoline.startLoop(TrampolineEC.scala:93)
at cats.effect.internals.Trampoline.execute(Trampoline.scala:43) at
cats.effect.internals.TrampolineEC.execute(TrampolineEC.scala:44) at
cats.effect.internals.IOBracket$BracketStart.apply(IOBracket.scala:72)
at
cats.effect.internals.IOBracket$BracketStart.apply(IOBracket.scala:52)
at
cats.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:136)
at
cats.effect.internals.IORunLoop$RestartCallback.signal(IORunLoop.scala:355)
at
cats.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.scala:376)
at
cats.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.scala:316)
at cats.effect.internals.IOShift$Tick.run(IOShift.scala:36) at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at 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
)
代码会将 $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%'
为什么已经描述JGH。
一个简单的修复方法是将 %
添加到参数中。
要求:
val s = sql"SELECT * FROM books WHERE title LIKE $title".query[Book].option
示例:
findNamePref("Title")
findNamePref("Tit%")
findNamePref("%itle")
findNamePref("%")
您收到此错误的原因是您在字符串本身中写入了一个字符串变量,即在您的案例中为标题。在使用时,字符串变量被替换为它的值,因此在双引号内写一个字符串值也是一个语法错误。所以,
您应该通过将标题值连接到 select 查询字符串来明确使用标题。
"select * from.... Where title like %"
+title+"%" ;
感谢大家。毕竟这是我使用的:
sql"SELECT * FROM books WHERE title LIKE ${title+"%"}".query[Book].option
我正在使用带有 Scala 和 Doobie 的 PostgreSQL 12.1。尝试使用 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()
}
异常:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: syntax error at end of input Position: 41 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2505) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2241) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:310) at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:447) at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:368) at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:158) at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:108) at doobie.free.KleisliInterpreter$PreparedStatementInterpreter.$anonfun$executeQuery(kleisliinterpreter.scala:956) at doobie.free.KleisliInterpreter.$anonfun$primitive(kleisliinterpreter.scala:112) at cats.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:87) at cats.effect.internals.IORunLoop$.startCancelable(IORunLoop.scala:41) at cats.effect.internals.IOBracket$BracketStart.run(IOBracket.scala:86) at cats.effect.internals.Trampoline.cats$effect$internals$Trampoline$$immediateLoop(Trampoline.scala:70) at cats.effect.internals.Trampoline.startLoop(Trampoline.scala:36) at cats.effect.internals.TrampolineEC$JVMTrampoline.super$startLoop(TrampolineEC.scala:93) at cats.effect.internals.TrampolineEC$JVMTrampoline.$anonfun$startLoop(TrampolineEC.scala:93) at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18) at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:94) at cats.effect.internals.TrampolineEC$JVMTrampoline.startLoop(TrampolineEC.scala:93) at cats.effect.internals.Trampoline.execute(Trampoline.scala:43) at cats.effect.internals.TrampolineEC.execute(TrampolineEC.scala:44) at cats.effect.internals.IOBracket$BracketStart.apply(IOBracket.scala:72) at cats.effect.internals.IOBracket$BracketStart.apply(IOBracket.scala:52) at cats.effect.internals.IORunLoop$.cats$effect$internals$IORunLoop$$loop(IORunLoop.scala:136) at cats.effect.internals.IORunLoop$RestartCallback.signal(IORunLoop.scala:355) at cats.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.scala:376) at cats.effect.internals.IORunLoop$RestartCallback.apply(IORunLoop.scala:316) at cats.effect.internals.IOShift$Tick.run(IOShift.scala:36) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at 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
)
代码会将 $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%'
为什么已经描述JGH。
一个简单的修复方法是将 %
添加到参数中。
要求:
val s = sql"SELECT * FROM books WHERE title LIKE $title".query[Book].option
示例:
findNamePref("Title")
findNamePref("Tit%")
findNamePref("%itle")
findNamePref("%")
您收到此错误的原因是您在字符串本身中写入了一个字符串变量,即在您的案例中为标题。在使用时,字符串变量被替换为它的值,因此在双引号内写一个字符串值也是一个语法错误。所以, 您应该通过将标题值连接到 select 查询字符串来明确使用标题。
"select * from.... Where title like %"
+title+"%" ;
感谢大家。毕竟这是我使用的:
sql"SELECT * FROM books WHERE title LIKE ${title+"%"}".query[Book].option