You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Slick 3.3.3操作DB2自增主键表执行UPDATE报错的解决方案

问题根源

Slick 执行.update(实体对象)时,会默认读取Table类中*投影定义的所有字段生成UPDATE语句的SET子句,你的定义里包含了带O.AutoInc属性的自增主键RECORD_ID,而DB2禁止修改自增主键列,因此抛出SQLCODE=-798错误。

最优解决方案

这里提供两种生产环境常用的方案,均比DELETE+INSERT的实现更安全、性能更好:

方案1:给自增主键标记不可更新(推荐,改动最小)

Slick 3.2及以上版本支持给列添加O.Updatable(false)属性,标记该字段不会出现在默认生成的UPDATE语句中。
仅需修改SomethingTbl的record_id列定义即可:

def record_id: Rep[Long] = column[Long]("RECORD_ID", O.PrimaryKey, O.AutoInc, O.Updatable(false))

修改后原有update方法不需要任何调整,Slick自动生成的UPDATE语句会自动排除RECORD_ID字段,完全符合你的预期。

方案2:手动指定需要更新的字段(灵活可控)

如果仅需更新少量字段,你可以在编写更新逻辑时显式指定要修改的列,完全自主控制SET子句内容:
修改updateSomething方法实现如下:

private def updateSomething(e: SomethingRec): FixedSqlAction[Int, NoStream, Effect.Write] = {
  someThings
    .filter(_.record_id === e.record_id)
    .map(_.status) // 仅选中需要更新的STATUS字段
    .update(e.status) // 传入对应新值
}

如果需要同时更新多个字段,调整map和update的参数即可:

// 示例:同时更新STATUS和REMARK两个字段
.map(t => (t.status, t.remark))
.update((e.status, e.remark))
注意事项
  • 不推荐使用DELETE+INSERT的替代方案:该方案会额外消耗自增序列号、降低操作性能,并发场景下还可能引发事务一致性问题。
  • 两种方案均兼容你当前使用的Slick 3.3.3、Scala 2.12版本,不需要额外升级依赖。

内容的提问来源于stack exchange,提问作者radumanolescu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:54:07