我想将自动生成的 ID 从插入返回到带有标识字段的 SQL Server 表中
我的第一次尝试是使用 SQL Server 的 @@IDENTITY 功能和我的插入语句,它返回带有 ID 的单行/列结果集。
IE)
val fooId = db.withSession((session: scala.slick.session.Session) => {
(sql"""
INSERT INTO Foo VALUES ('bar')
SELECT @@IDENTITY""").as[Int].first()(session)
})
但是,在这种情况下,slick 总是返回 1。
编辑:我撒谎了,它总是返回 1,我认为这是受影响的行数。作为测试,我尝试像这样修改查询以查看会发生什么,我收到一个异常“java.lang.ClassCastException:java.lang.Integer cannot be cast to scala.Tuple2”。在这种情况下,它看起来需要返回一个标量。
val fooIdTuple = db.withSession((session: scala.slick.session.Session) => {
(sql"""
INSERT INTO Foo VALUES ('bar')
SELECT @@IDENTITY as Foo, 47 as Bar""").as[(Int, Int)].first()(session)
})
编辑 2:这行得通,但我认为它进行了两次往返。这可能意味着它也可能成为竞争条件的受害者:
val fooId = db.withSession((session: scala.slick.session.Session) => {
(sql"""INSERT INTO Foo VALUES ('bar')""").as[Int].first()(session)
(sql"""SELECT @@IDENTITY""").as[Int].first()(session)
})
编辑 3:我对此想得越多,我就越清楚,考虑到我对 slick 的使用,这并不是一个真正的巧妙话题,而是更多的 SQL Server 和 JDBC 问题。这是我最新的解决方案。
val fooId = db.withSession((session: scala.slick.session.Session) => {
(sql"""
SET NOCOUNT ON
INSERT INTO Foo VALUES ('bar')
SET NOCOUNT OFF
SELECT @@IDENTITY""").as[Int].first()(session)
})
编辑 4:这是最简洁的解决方案。它利用了 SQL Server 的OUTPUT 功能(感谢 PB)。
val fooId = db.withSession((session: scala.slick.session.Session) => {
(sql"""INSERT INTO Foo OUTPUT INSERTED.FooId VALUES ('bar')""").as[Int].first()(session)})