Squeryl动态连接子句

时间:2013-06-20 19:31:11

标签: sql scala join dynamic squeryl

我正在寻找的东西看起来相当普遍,但我似乎无法通过Squeryl api弄明白。我需要在我的on语句中有一个条件片段来加入。

def getAllJoined(
  hasFallback:Option[String] = None
  ):List[(Type1,Type2)] = transaction{
  join(mainTable,
    table2,
    table3,
    table3,
    table4.leftOuter,
    table4.leftOuter,
    table5,
    table6)((main, attr1, attr2, attr3, attr4, attr5, attr6, attr7) =>
    select(main,attr1,attr2,attr3,attr4,attr5,attr6,attr7)
    on(
      //if(hasFallback.isDefined) (main.fallBack).isNotNull else 1 === 1.inhibitWhen(true)
      (main.attr1Col === attr1.id) ,
      (main.attr2Col === attr2.id) ,
      (main.attr3Col === attr3.id) ,
      (main.attr4Col === attr4.map(_.id)) ,
      (main.attr5Col === attr5.map(_.id)) ,
      (main.attr6Col === attr6.id) ,
      (main.attr7Col === attr7.id)
      )
  ).toList

我不知道怎么能得到这个。我已经考虑过如下事情,或者做我在这里评论过的事情。

底线基本上是如果我打开了hasFallback标志,我只需要返回具有此列的对象不为null(已定义)。否则,如果没有hasFallback标志,则忽略它是否已定义。

编辑:看起来on方法只能接受七个参数。有没有办法绕过这七个参数限制?

另外,type mismatch; found : org.squeryl.dsl.boilerplate.JoinQueryYield6[myTuple] required: org.squeryl.dsl.boilerplate.JoinQueryYield7[?] 显然,无论如何我都被迫有7个理由?不多也不少。

直接来自squeryl网站

  

如果连接有N个参数,'on'函数必须带N-1个参数,   第i个'on'条件对应于第i个表的表达式:

join(T, A1, A2,... AN)((a1,a2,...,aN) =>
  ...
  on(...condition for a1...,...condition for a2...,......condition for aN..., )
)

解决方案:对于遇到同样问题的其他任何人来说,这里是使用where子句的解决方案。

...table6)((main, attr1, attr2, attr3, attr4, attr5, attr6, attr7) =>
where(
    main.fallBack.isNotNull.inhibitWhen(!hasFallback.isDefined)
    )
    select(main,attr1,attr2,attr3,attr4,attr5,attr6,attr7)...

2 个答案:

答案 0 :(得分:1)

如果您只是想在where子句中添加条件,则可以执行以下操作:

on(
   t1.secondary === t2.id and
   (if(hasFallback.isDefined) t1.fallback.isNotNull else 1 === 1.inhibitWhen(true))
)

inhibitWhen子句应始终阻止1 === 1的输出显示在实际的SQL中,但它允许if / else返回LogicalBoolean

答案 1 :(得分:0)

有关github和谷歌小组的类似问题的讨论:

https://github.com/max-l/Squeryl/pull/168

https://github.com/max-l/Squeryl/pull/144

https://groups.google.com/forum/#!topic/squeryl/BBAXbtRq9v4

如果您使用的是squeryl-0.9.5-6,那么您应该找到自己的方法。我选择以下列方式做(类似的任务):

    /** thin wrappwer with no runtime cost */
    implicit class RichLogicalBoolean(val e: LogicalBoolean) extends AnyVal {
        def and(condition: Boolean, other: LogicalBoolean) = if (condition) other and e else e
    }

在此之后,我可以编写如下代码:

t1.secondary === t2.id and
    (yourCondition, t1.fallback.isNotNull)