简体   繁体   English

如何使用Slick 3.0调用MySQL中的存储过程和定义的函数

[英]How to call Stored Procedures and defined functions in MySQL with Slick 3.0

I have defined in my db something like this 我在我的数据库中定义了这样的东西

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;

Now I have received an answer from Stefan Zeiger (Slick lead) redirecting me here: User defined functions in Slick 现在我收到了Stefan Zeiger的回答(Slick领导),我在这里重定向: Slick中的用户定义函数

I have tried (having the following object in scope): 我试过(在范围内有以下对象):

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)

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

I have also tried while having an application.conf in src/main/resources like this: 我也尝试过在src / main / resources中有一个application.conf,如下所示:

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

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

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

Result: 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) ^ 结果: 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) ^

I am also planning to call stored procedures that return one tuple of three values, via sql"call myProc(v1) .as[(Int, Int, Int)] 我还计划通过sql"call myProc(v1) .as [(Int,Int,Int)] sql"call myProc(v1)返回三个值的三元组的存储过程

Any ideas? 有任何想法吗?

EDIT: When making sql""""SELECT COUNT(DISTINCT LOYAL3_SHARED_HOLDER_ID) FROM stocks_x_hldr WHERE STOCK_TICKER_SIMBOL = issuer AND QUANT_PURCHASES > QUANT_SALES""".as[(Int)] results in SqlStreamingAction[Vector[Int], Int, Effect] instead of the suggested DBIO[Int] (from what I infer) suggested by the documentation 编辑:当使用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] (根据我的推断)

I've been running into exactly the same problem for the past week. 过去一周我一直遇到完全相同的问题。 After some extensive research ( see my post here , I'll be adding a complete description of what I've done as a solution), I decided it can't be done in Slick... not strictly speaking. 经过一些广泛的研究( 参见我在这里的帖子 ,我将添加一个完整的描述,我已经做了解决方案),我认为它不能在Slick中完成......严格来说。

But, I'm resistant to adding pure JDBC or Anorm into our solution stack, so I did find an "acceptable" fix, IMHO. 但是,我拒绝在我们的解决方案堆栈中添加纯JDBC或Anorm,所以我找到了一个“可接受的”修复程序,恕我直言。

The solution is to get the session object from Slick, and then use common JDBC to manage the stored function / stored procedure calls. 解决方案是从Slick获取会话对象,然后使用通用JDBC来管理存储的函数/存储过程调用。 At that point you can use any third party library that makes it easier... although in my case I wrote my own function to set up the call and return a result set. 此时,您可以使用任何第三方库,使其更容易...虽然在我的情况下,我编写了自己的函数来设置调用并返回结果集。

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()

I know that's pretty terse, but as I said, see the other thread for a more complete posting. 我知道这很简洁,但正如我所说,请看另一个帖子以获得更完整的帖子。 I'm putting it together right now and will post the answer shortly. 我现在把它放在一起,很快就会发布答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM