Anorm返回0结果,而psql返回2结果

时间:2015-09-22 04:20:26

标签: 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.*)
}

}

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

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

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

编辑:当我切换anorm代码以使用String Interpolation时,我得到:

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

EDIT2:我也试过传递'%...%'与searchString一起进入LIKE并且仍然得到0结果。

1 个答案:

答案 0 :(得分:1)

有两个问题 - 列的名称和过滤器值

对于过滤器值:您必须省略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注入。

<强>更新

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

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

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

更新2

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

但是当你使用PostgreSQL时我建议明确的来源:PostgreSQL日志:postgresql.conf

  

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

然后您将在PostgreSQL日志文件中看到类似这样的内容:

  

日志:从test50中选择*,其中名称为$ 1

     

详细信息:参数:$ 1 ='%aaa'