Slick - 使用多个表更新查询

Posted

技术标签:

【中文标题】Slick - 使用多个表更新查询【英文标题】:Slick - Update query with multiple tables 【发布时间】:2019-07-18 09:11:19 【问题描述】:

我目前在我的 scala-slick3 项目中遇到更新查询的问题。我有一个Report-Class,其中包含多个Products,每个Product 包含多个Parts。我想实现一个函数,将这个Report 中的每个Product 中的每个Part 标记为assessed

我想过做这样的事情:

 def markProductPartsForReportAsAssessed(reportId: Int) = 
     val query = for 
         (products, parts) <- (report_product_query filter(_.reportId === reportId) 
                               join (part_query filter(_.isAssessed === false)) 
                               on (_.productId === _.productId))
       yield parts.isAssessed

      db.run(query.update(true))
 

现在,当我运行这段代码时,slick 会抛出这个异常: SlickException: A query for an UPDATE statement must resolve to a comprehension with a single table。 我已经研究过他们的解决方案(如this 或this)对我来说并不是很满意的类似问题。

为什么 slick 会抛出这个异常,或者为什么一开始就有问题?我的印象是我的yield 已经照顾到不“更新多个表”。

提前致谢!

【问题讨论】:

【参考方案1】:

我猜这是因为 UPDATE 查询只需要一张表。如果为上面的查询写SQL,就可以了

UPDATE parts a SET isAccessed = 'true' 
WHERE a.isAccessed = 'false' and 
exists(select 'x' from products b 
where a.productId = b.producId and b.reportId = reportId)

因此,您可以将与“产品”表相关的条件放入过滤器中,如下所示。

val reportId = "123" // some variable
val subQuery = (reportId:Rep[String], productId:Rep[String]) =>
 report_product_query.filter(r => r.report_id === reportId && r.product_id === productId)
val query = part_query.filter(p => p.isAccesssed === false:Rep[Boolean] && 
subQuery(reportId, p.productId).exists).map(_.isAccessed)
db.run(query.update(true))

【讨论】:

以上是关于Slick - 使用多个表更新查询的主要内容,如果未能解决你的问题,请参考以下文章

在一个灵活的查询中从多个表中删除行

Scala slick 2.0 updateAll 等同于 insertALL?

MySQL,一次查询更新多个表

MySQL,一次查询更新多个表

如何使用 Access ODBC 通过一个查询更新多个表?

如何使用结果查询更新多个表?