【问题标题】:Slick Plain SQL Query with Dynamic Conditions具有动态条件的 Slick 普通 SQL 查询
【发布时间】:2015-12-27 23:41:20
【问题描述】:

我正在努力为我的查询添加额外的条件。在最简单的形式中,我需要的是如下所示:

def findPeople(name: String, maybeSurname: Option[String]) = {
   val sql1 = sql"select * from my_table where name = $name"
   val sql2 = maybeSurname.map( surname => sql"and col2 = $surname" ).getOrElse(sql"")
   val finalSql = sql1 + sql2 // I need this kind of feature
   ...
   ...
}

使用#$ 可能是一种选择,但随后 surname 将不是绑定变量,这是一个大问题。

【问题讨论】:

    标签: scala slick


    【解决方案1】:

    这是 slick 3.1.x 上的示例测试

    import slick.jdbc.{SQLActionBuilder, SetParameter, PositionedParameters}
    
    object SlickKit {
    
      implicit class SQLActionBuilderConcat (a: SQLActionBuilder) {
        def concat (b: SQLActionBuilder): SQLActionBuilder = {
          SQLActionBuilder(a.queryParts ++ b.queryParts, new SetParameter[Unit] {
            def apply(p: Unit, pp: PositionedParameters): Unit = {
              a.unitPConv.apply(p, pp)
              b.unitPConv.apply(p, pp)
            }
          })
        }
      }
    }
    

    然后

    import SlickKit._
    val sql1 =
      sql"""
       select count(*) from idinfo_#$i
        """
    
    val sql2 =
      sql"""
           where source=$source
        """
    
    val sql = sql1 concat sql2
    
    sql.as[Int].head
    

    【讨论】:

    • 这是连接值吗,可以防止 SQL 注入吗??
    【解决方案2】:

    我认为绑定变量不会被 map 函数解释。它们由 Slick sql 插值器解释。这就是为什么你的 sql2 不会得到 surname 值的原因。

    如果您需要编写 SQL 语句,也许您可​​以考虑不使用普通 SQL 功能。你可以只做 .filter(.name ==== name ).filter(.col2 === surname) 吗?

    【讨论】:

    • 我的查询比这个复杂得多,这就是我使用普通 SQL 的原因。
    • 我假设sql2 是一个部分查询,这在现在的 slick 中是不可能的。如果你的意思是maybeSurname.map,那是Option,而不是绑定变量。
    • 感谢您的回答。 Quill Infix Operator 有类似的方法吗?提前致谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 2017-02-24
    相关资源
    最近更新 更多