来自 select 的 Squeryl 更新?

Squeryl update from select?

给出以下小部件table

╔════╦═════════╦═════╗
║ id ║ prev_id ║ foo ║
╠════╬═════════╬═════╣
║  1 ║         ║ bar ║
║  2 ║       1 ║     ║
╚════╩═════════╩═════╝

以及下面的sql查询

UPDATE widgets 
SET 
  widgets.foo = 
    (
     SELECT widgets.foo
     FROM widgets 
     WHERE widgets.id = 1
    )
WHERE
    widgets.id = 2

如何在 squeryl 中进行上述更新?

我试过了

  update(widgets) (
    w=>
      where(w.id === 2)
        set(w.foo := from(widgets)(prevW => where(prevW.id === 1) select foo))
  )

但这给了我以下编译错误:

error: No implicit view available from org.squeryl.Query[Option[String]] => org.squeryl.dsl.ast.TypedExpressionNode[Option[org.squeryl.PrimitiveTypeMode.StringType]].

看起来 Squeryl 添加了对 https://github.com/max-l/Squeryl/commit/e75ddecf4a0855771dd569b4c4df4e23fde2133e

子查询的支持

然而,它需要一个保证 return 一个结果的聚合查询。这是通过 compute 子句完成的。

我想出了一个使用 compute(min(foo)) 的解决方法。

所以我的解决方案最终看起来像

update(widgets) (
  w=>
    where(w.id === 2)
    set(w.foo := from(widgets)(prevW => where(prevW.id === 1) compute(min(foo))))
)

也许应该有一个 single 聚合函数,如果查询 return 有多个结果,它会抛出异常。

相关对话: