Slick update table 使用自动生成的主键
Slick update table with auto-generated primary key
我在 Scala 中有一个简单的案例 class,我使用自动生成的主键(序列号)映射到 DB2 table。 Slick DAO 对 INSERT 和 SELECT 工作正常,但对 UPDATE 抛出异常。
Slick 显示生成的 SQL,问题似乎在于它试图(也)更新主键列,而 DB2 不允许这样做。
这是 Slick 生成的 SQL 语句:
slick.basic.BasicBackend.action - [update "SOME_THING" set "RECORD_ID" = ?, "STATUS" = ? where "RECORD_ID" = ...]
因为我只是想更新 STATUS
,这就是我想要的(并且应该有效):
slick.basic.BasicBackend.action - [update "SOME_THING" set "STATUS" = ? where "RECORD_ID" = ...]
如何修改我的代码以使更新生效?我可以用 DELETE+INSERT 替换 UPDATE,但是有更好的方法吗?
使用 Slick 3.3.3、Scala 2.12。
import slick.jdbc.DB2Profile.api._
import slick.lifted.ProvenShape
class SomethingTbl(tag: Tag, schemaName: String) extends Table[SomethingRec](tag, _schemaName = Some(schemaName), _tableName = "SOME_THING") {
def record_id: Rep[Long] = column[Long]("RECORD_ID", O.PrimaryKey, O.AutoInc)
def status: Rep[String] = column[String]("STATUS")
override def * : ProvenShape[SomethingRec] = (record_id, status ) <> (SomethingRec.tupled, SomethingRec.unapply)
}
import akka.actor.ActorSystem
import slick.jdbc
import slick.jdbc.DB2Profile
import slick.sql.FixedSqlAction
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
class SomethingDAO(schemaName: String)(implicit val system: ActorSystem) {
import slick.jdbc.DB2Profile.api._
lazy val someThings: TableQuery[SomethingTbl] =
TableQuery[SomethingTbl](tag => new SomethingTbl(tag, schemaName))
// Capture the DB-generated sequence number and return it
private lazy val insertSomething: jdbc.DB2Profile.IntoInsertActionComposer[SomethingRec, SomethingRec] =
someThings returning someThings.map(_.record_id) into ((rec, record_id) => rec.copy(record_id = record_id))
private implicit val db: DB2Profile.backend.Database = Database.forConfig("slick-db2")
def update(e: SomethingRec): Int = {
val recordFut = db.run(updateSomething(e))
val record = Await.result(recordFut, Duration.Inf)
record
}
private def updateSomething(e: SomethingRec): FixedSqlAction[Int, NoStream, Effect.Write] = {
someThings
.filter(_.record_id === e.record_id)
.update(e)
// com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-798, SQLSTATE=428C9, SQLERRMC=RECORD_ID, DRIVER=4.19.26
}
}
修改如下代码,生效
private def updateSomething(e: SomethingRec): FixedSqlAction[Int, NoStream, Effect.Write] = {
val q = for {c <- someThings if c.record_id === e.record_id} yield c.status
q.update(e.status)
}
我在 Scala 中有一个简单的案例 class,我使用自动生成的主键(序列号)映射到 DB2 table。 Slick DAO 对 INSERT 和 SELECT 工作正常,但对 UPDATE 抛出异常。
Slick 显示生成的 SQL,问题似乎在于它试图(也)更新主键列,而 DB2 不允许这样做。
这是 Slick 生成的 SQL 语句:
slick.basic.BasicBackend.action - [update "SOME_THING" set "RECORD_ID" = ?, "STATUS" = ? where "RECORD_ID" = ...]
因为我只是想更新 STATUS
,这就是我想要的(并且应该有效):
slick.basic.BasicBackend.action - [update "SOME_THING" set "STATUS" = ? where "RECORD_ID" = ...]
如何修改我的代码以使更新生效?我可以用 DELETE+INSERT 替换 UPDATE,但是有更好的方法吗?
使用 Slick 3.3.3、Scala 2.12。
import slick.jdbc.DB2Profile.api._
import slick.lifted.ProvenShape
class SomethingTbl(tag: Tag, schemaName: String) extends Table[SomethingRec](tag, _schemaName = Some(schemaName), _tableName = "SOME_THING") {
def record_id: Rep[Long] = column[Long]("RECORD_ID", O.PrimaryKey, O.AutoInc)
def status: Rep[String] = column[String]("STATUS")
override def * : ProvenShape[SomethingRec] = (record_id, status ) <> (SomethingRec.tupled, SomethingRec.unapply)
}
import akka.actor.ActorSystem
import slick.jdbc
import slick.jdbc.DB2Profile
import slick.sql.FixedSqlAction
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
class SomethingDAO(schemaName: String)(implicit val system: ActorSystem) {
import slick.jdbc.DB2Profile.api._
lazy val someThings: TableQuery[SomethingTbl] =
TableQuery[SomethingTbl](tag => new SomethingTbl(tag, schemaName))
// Capture the DB-generated sequence number and return it
private lazy val insertSomething: jdbc.DB2Profile.IntoInsertActionComposer[SomethingRec, SomethingRec] =
someThings returning someThings.map(_.record_id) into ((rec, record_id) => rec.copy(record_id = record_id))
private implicit val db: DB2Profile.backend.Database = Database.forConfig("slick-db2")
def update(e: SomethingRec): Int = {
val recordFut = db.run(updateSomething(e))
val record = Await.result(recordFut, Duration.Inf)
record
}
private def updateSomething(e: SomethingRec): FixedSqlAction[Int, NoStream, Effect.Write] = {
someThings
.filter(_.record_id === e.record_id)
.update(e)
// com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-798, SQLSTATE=428C9, SQLERRMC=RECORD_ID, DRIVER=4.19.26
}
}
修改如下代码,生效
private def updateSomething(e: SomethingRec): FixedSqlAction[Int, NoStream, Effect.Write] = {
val q = for {c <- someThings if c.record_id === e.record_id} yield c.status
q.update(e.status)
}