postgresql - Anorm 返回 0 个结果,而 psql 返回 2 个结果

标签 postgresql scala anorm

我通过 AJAX 为搜索栏提供动力,该搜索栏传递与数据库列相关的选定过滤器(单选按钮)和搜索栏中输入的任何内容的搜索字符串。我使用的 scala/play/anorm 代码是这样的:

def searchDB(searchString: String, filter: String): List[DatabaseResult] = {
DB.withConnection { implicit c =>
  SQL(
    """
      SELECT name, email, emailsecondary, picture, linkedin, title, company, companylink, companydesc, location, github, stackoverflow, twitter, blog
      FROM mailinglistperson
      WHERE {filter} LIKE '%{searchString}%'
    """).on(
          'filter -> filter,
          'searchString -> searchString
    ).as(databaseResultParser.*)
}

当我使用与上述异常代码同构的 psql 在数据库 (PostgreSQL) 上运行查询时,它返回 2 个结果,即:

select id, name, email from mailinglistperson where company like '%kixer%';

但是当传递完全相同的值时,异常代码返回 0 个结果(我已经通过 println 验证了这些值)

编辑:当我将异常代码切换为使用字符串插值时,我得到:

[error] - play.core.server.netty.PlayDefaultUpstreamHandler - Cannot invoke the action
 java.lang.RuntimeException: No parameter value for placeholder: 3

EDIT2:我还尝试将“%...%”与 searchString 一起传递到 LIKE 中,但仍然得到 0 个结果。

最佳答案

有两个问题——列名和过滤值


至于过滤值:您必须在 SQL 命令中省略单个标记,并且您应该在参数中传递占位符“%”。如果是字符串,则会自动处理刻度。


至于列名:它就像一个字符串参数,因此也会自动处理报价:

[debug] c.j.b.PreparedStatementHandle - select ... from ... where 'filter' like '%aaa%'

一种解决方案:使用普通字符串插值 s"""... $filter ..."""


一起:

SQL(
  s"""
    SELECT name, email, ...
    FROM mailinglistperson
    WHERE $filter LIKE {searchString}
  """).on(
      'searchString -> "%" + searchString + "%"
  ).as(databaseResultParser.*)

但这之前应该伴随着检查,比如

val validColumns = List("name", "email")
if (validColumns.contains(filter)) == false) {
  throw new IllegalArgumentException("...")
}

防止 SQL 注入(inject)。


更新

正如 cchantep 所指出的:如果使用 Anorm >= 2.4,则可以使用混合插值(列名和值):

SQL"... WHERE #$filter LIKE $searchString"

在这种情况下,它对 SQL 注入(inject)是部分安全的:覆盖值,覆盖列名。

更新 2

关于记录 SQL 语句,请参阅 Where to see the logged sql statements in play2?

但是当您使用 PostgreSQL 时,我建议使用权威来源:PostgreSQL 日志:在 postgresql.conf 中:

log_statement = 'all' # none, ddl, mod, all

然后您将在 PostgreSQL 日志文件中看到如下内容:

LOG: select * from test50 where name like $1

DETAIL: Parameter: $1 = '%aaa'

关于postgresql - Anorm 返回 0 个结果,而 psql 返回 2 个结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32708317/

相关文章:

sql - jsonb 查询数组中的嵌套对象

SQL Insert Select 当select 检索多条记录时

scala - 如何让 Scalacheck arbString 只生成可读的字符串?

java - 基于 Spark 的应用程序在 JDK 8 中失败?

sql - 找不到参数连接的隐式值 : java. sql.Connection

python - 如何使用 SQLAlchemy 在 Postgres 数据库中创建包含 UUID 列的表?

database - 使用存储函数创建数据库

placeholder - play2的异常中sql的 "?"占位符在哪里

java - Scala 时区问题

json - 如何为 play-scala anorm pgsql 设置 jsonb[] 的类型