在 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}')")
一般来说,对于给定的模型,您应该能够在常规 where
或 select
方法中调用存储过程:
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。这对我很有用。
那里的例子很少,但没有一个是非常清楚的(或在旧版本上)。
我想调用 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}')")
一般来说,对于给定的模型,您应该能够在常规 where
或 select
方法中调用存储过程:
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。这对我很有用。