在 ROR 4 中调用 MySQL 存储过程

Calling MySQL stored procedure in ROR 4

那里的例子很少,但没有一个是非常清楚的(或在旧版本上)。

我想调用 MySQL 过程并检查 return 状态(在 rails 4.2 中)。我看到的最常见的方法是调用result = ActiveRecord::Base.connection.execute("call example_proc()"),但是有些地方有人写了准备好的方法result = ActiveRecord::Base.connection.execute_procedure("Stored Procedure Name", arg1, arg2)(但是没有编译)。

那么调用和获取 MySQL 程序状态的正确方法是什么?

编辑:

以及如何安全地发送参数,其中第一个参数是整数,第二个是字符串,第三个是布尔值?

Rails 4 ActiveRecord::Base 不支持 execute_procedure 方法,尽管 result = ActiveRecord::Base.connection 仍然有效。即

result = ActiveRecord::Base.connection.execute("call example_proc('#{arg1}','#{arg2}')")

你可以试试下面的毗湿奴方法

你也可以试试

ActiveRecord::Base.connections.exec_query("call example_proc('#{arg1}','#{arg2}')")

here is the document

一般来说,对于给定的模型,您应该能够在常规 whereselect 方法中调用存储过程:

YourModel.where("YOUR_PROC(?, ?)", var1, var2)

至于您的评论 "Bottom line I want the most correct approach with procedure validation afterwards (for warnings and errors)",我想这始终取决于您实际想要实现的内容以及您希望代码的可读性。

例如,如果您想要 return 行 YourModel 属性,那么将上述语句与 where 方法一起使用可能会更好。另一方面,如果您编写了一些 sql 适配器,那么您可能希望下降到 ActiveRecord::Base.connection.execute 级别。

顺便说一句,这里应该提到一些关于存储过程性能的内容。在一些数据库中,数据库对存储过程的第一个 运行 进行存储过程优化。但是,您传递给第一个 运行 的参数可能 而不是 是那些将在以后更频繁地 运行ning 的参数。因此,您的存储过程可能会根据您的情况以 "none-optimal" 的方式自动优化。它可能会或可能不会以这种方式发生,但这是您在使用带有动态参数的存储过程时应该考虑的事情。

我相信您已经尝试过许多其他解决方案并遇到了一些或其他错误,主要是“不同步”或“关闭连接”错误。这些错误在您尝试执行查询时每隔 SECOND 发生一次。我们需要像每次连接都是新连接一样的解决方法来克服这个问题。这是我没有抛出任何错误的解决方案。

#checkout a connection for Model
conn = ModelName.connection_pool.checkout

#use the new connection to execute the query
@records = conn.execute("call proc_name('params')")

#checkout the connection
ModelName.connection_pool.checkin(conn)

其他方法对我来说都失败了,可能是因为 ActiveRecord 连接被自动处理以检查每个线程。当我们的方法尝试检查一个连接只是为了执行 SP 时,它可能会发生冲突,因为在方法启动时会有一个活动连接。

因此,我们的想法是手动#checkout 模型的连接,而不是从池中为 thread/function 手动检查连接,并在工作完成后#checkin。这对我很有用。