【问题标题】:How to call Stored Procedures and defined functions in MySQL with Slick 3.0如何使用 Slick 3.0 在 MySQL 中调用存储过程和定义函数
【发布时间】:2015-07-30 05:33:53
【问题描述】:

我在我的数据库中定义了这样的东西

CREATE FUNCTION fun_totalInvestorsFor(issuer varchar(30)) RETURNS INT
NOT DETERMINISTIC
BEGIN
  RETURN (SELECT COUNT(DISTINCT LOYAL3_SHARED_HOLDER_ID) 
      FROM stocks_x_hldr
      WHERE STOCK_TICKER_SIMBOL = issuer AND
            QUANT_PURCHASES > QUANT_SALES);
END;

现在我收到了 Stefan Zeiger(Slick 领导)的回复,将我重定向到这里:User defined functions in Slick

我已经尝试过(范围内有以下对象):

lazy val db = Database.forURL("jdbc:mysql://localhost:3306/mydb",
driver = "com.mysql.jdbc.Driver", user = "dev", password = "root")
val totalInvestorsFor = SimpleFunction.unary[String, Int]("fun_totalInvestorsFor")
totalInvestorsFor("APPLE") should be (23)

结果:Rep(slick.lifted.SimpleFunction$$anon$2@13fd2ccd fun_totalInvestorsFor, false) was not equal to 23

我也尝试过在 src/main/resources 中有一个 application.conf,如下所示:

tsql = {
  driver = "slick.driver.MySQLDriver$"
  db {
    connectionPool = disabled
    driver = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://localhost/mydb"
  }
}

然后在我的代码中使用@StaticDatabaseConfig("file:src/main/resources/application.conf#tsql")

tsql"select fun_totalInvestorsFor('APPLE')" should be (23)

结果:Error:(24, 9) Cannot load @StaticDatabaseConfig("file:src/main/resources/application.conf#tsql"): No configuration setting found for key 'tsql' tsql"select fun_totalInvestorsFor('APPLE')" should be (23) ^

我还计划通过sql"call myProc(v1).as[(Int, Int, Int)] 调用返回三个值的一个元组的存储过程

有什么想法吗?

编辑:制作时 sql""""SELECT COUNT(DISTINCT LOYAL3_SHARED_HOLDER_ID) FROM stocks_x_hldr WHERE STOCK_TICKER_SIMBOL = issuer AND QUANT_PURCHASES > QUANT_SALES""".as[(Int)] 结果是SqlStreamingAction[Vector[Int], Int, Effect],而不是文档建议的DBIO[Int](据我推断)

【问题讨论】:

  • 试试totalInvestorsFor("APPLE") should be LiteralColumn(23)
  • Rep(slick.lifted.SimpleFunction$$anon$2@2d710f1a fun_totalInvestorsFor, false) was not equal to Rep(LiteralNode 23 (volatileHint=false))
  • 它是一个数据库函数。它需要通过要评估的查询内部的数据库。否则,它只是数据库端应该发生的事情的表达式树,而不是结果。
  • your sql"..." 东西应该是一个 DBIO[Vector[Int]]... 我认为是,因为 SqlStreamingAction 是 DBIOAction 的子类型,别名为 DBIO跨度>
  • 尝试调用 db.run 看看你得到了什么

标签: mysql scala slick-3.0


【解决方案1】:

在过去的一周里,我遇到了完全相同的问题。经过一些广泛的研究(see my post here,我将添加对我所做的解决方案的完整描述),我决定它不能在 Slick 中完成......严格来说不是。

但是,我反对将纯 JDBC 或 Anorm 添加到我们的解决方案堆栈中,所以我确实找到了一个“可接受的”修复,恕我直言。

解决的办法是从Slick获取会话对象,然后使用普通的JDBC来管理存储函数/存储过程调用。那时,您可以使用任何第三方库来简化它......尽管在我的情况下,我编写了自己的函数来设置调用并返回结果集。

val db = Database.forDataSource(DB.getDataSource)
var response: Option[GPInviteResponse] = None

db.withSession {
    implicit session => {
        // Set up your call here... (See my other post for a more detailed
        // answer with an example:
        // procedure is eg., "{?=call myfunction(?,?,?,?)}"
        val cs = session.conn.prepareCall(procedure.toString)
        // Set up your in and out parameters here
        // eg. cs.setLong(index, value)
        val result = cs.execute()
        val rc = result.head.asInstanceOf[Int]

        response = rc match {
            // Package up the response to the caller
        }
    }
}
db.close()

我知道这很简洁,但正如我所说,请参阅另一个帖子以获得更完整的帖子。我现在把它放在一起,很快就会发布答案。

【讨论】:

  • 这比以前的 interpolation 和通过以前版本的 Slick 在范围内具有隐式 Session 的声明性和 FP 少得多,我想我是回到那个。谢谢扎克!
猜你喜欢
  • 1970-01-01
  • 2018-11-28
  • 2017-04-23
  • 2020-05-10
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
相关资源
最近更新 更多