【问题标题】:How do I return an auto generated ID using Slick plain SQL with SQL Server如何使用带有 SQL Server 的 Slick 纯 SQL 返回自动生成的 ID
【发布时间】:2013-10-02 20:33:28
【问题描述】:

我想将自动生成的 ID 从插入到带有标识字段的 SQL Server 表中返回

我的第一次尝试是使用 SQL Server 的 @@IDENTITY 功能和我的插入语句,返回带有 ID 的单行/列结果集。

即)

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 的使用,这并不是一个真正的 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 feature(感谢 PB)。

val fooId = db.withSession((session: scala.slick.session.Session) => { 
  (sql"""INSERT INTO Foo OUTPUT INSERTED.FooId VALUES ('bar')""").as[Int].first()(session)})

【问题讨论】:

  • 为自己解决问题点赞。 :)

标签: sql-server scala jdbc slick


【解决方案1】:

鉴于我对 slick(纯 SQL)的使用,这并不是一个真正的巧妙主题,而更像是一个 SQL Server 问题。

这是最简洁的解决方案。它利用了 SQL Server 的OUTPUT feature(感谢 PB)。

val fooId = db.withSession((session: scala.slick.session.Session) => { 
  (sql"""INSERT INTO Foo OUTPUT INSERTED.FooId VALUES ('bar')""").as[Int].first()(session)})

【讨论】:

    【解决方案2】:

    只是摸不着头脑...在INSERT 语句后添加分号可以解决问题吗?

    val fooId = db.withSession((session: scala.slick.session.Session) => { 
      (sql"""
    INSERT INTO Foo VALUES ('bar');
    SELECT @@IDENTITY""").as[Int].first()(session)
    })
    

    【讨论】:

      【解决方案3】:

      如果我使用您的示例,则会发生错误。 userId 是 mySQL 表中的自动增量字段。

      sql"""
         INSERT INTO `table`(`email`) 
         OUTPUT INSERTED.userId 
         VALUES ("theEmailAdress@test.de")
      """.as[Int].firstOption
      

      难道没有 slick/plainSQL 原生解决方案来检索当前 INSERT 的自动递增 id 吗?

      【讨论】:

      • 我使用的是 MSSQL,而不是 MySQL。当时我正在使用 plainSQL 和 slick 并没有解决方案。尽管他们的 MSSQL 驱动程序使用他们的 DSL(不是 plainSQL)确实支持我读过的内容。
      • 感谢您的回答。最后我找到了一种用plainSQL检索id的方法。见这里:stackoverflow.com/questions/22013105/…
      • 很高兴你知道了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多