Sea*_*ver 7 sql-server scala jdbc slick
我想将插入的自动生成的ID返回到带有标识字段的SQL Server表中
我的第一次尝试(返回带有ID的单行/列结果集)是使用SQL Server的@@ IDENTITY功能以及我的insert语句.
即)
val fooId = db.withSession((session: scala.slick.session.Session) => {
(sql"""
INSERT INTO Foo VALUES ('bar')
SELECT @@IDENTITY""").as[Int].first()(session)
})
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,光滑总是返回1.
编辑:我说谎,它总是返回1,我认为是受影响的行数.作为一个测试,我尝试修改查询,这样看看会发生什么,我收到一个异常"java.lang.ClassCastException:java.lang.Integer不能强制转换为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)
})
Run Code Online (Sandbox Code Playgroud)
编辑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)
})
Run Code Online (Sandbox Code Playgroud)
编辑3:我对此的思考越多,我就越清楚,因为我使用了光滑的东西,这不是一个简单的主题,而是更多的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)
})
Run Code Online (Sandbox Code Playgroud)
编辑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)})
Run Code Online (Sandbox Code Playgroud)
考虑到我对 slick(普通 SQL)的使用,这并不是一个真正的 slick 主题,而更像是一个 SQL Server 问题。
这是最简洁的解决方案。它利用了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)})
Run Code Online (Sandbox Code Playgroud)