【发布时间】:2022-08-15 13:22:20
【问题描述】:
我有一张名为Coupon 的表。
该表有一个名为query 的列,其中包含一个字符串。
query 字符串中有一些逻辑条件,格式为where 语句。例如:
coupon1.query
=> \" \'/hats\' = :url \"
coupon2.query
=> \" \'/pants\' = :url OR \'/shoes\' = :url \"
我想编写一个存储过程,将 2 个参数作为输入:Coupon id 列表和变量(在本例中为当前 URL)。
我希望该过程从每个Coupon 中查找query 列的值。然后它应该在 where 语句中运行该字符串,插入我的其他参数(当前 url),然后返回任何匹配的 Coupon id。
鉴于上面的两张优惠券,这就是我期望程序的行为方式。
Example 1:
* Call procedure with ids for coupon1 and coupon2, with @url = \'/hats\'
* Expect coupon1 to be returned.
Example 2:
* Call procedure with ids for coupon1 and coupon2, with @url = \'/pants\'
* Expect coupon2 to be returned.
Example 3:
* Call procedure with ids for coupon1 and coupon2, with @url = \'/shirts\'
* Expect no ids returned. URL does not match \'/hats\' for coupon1, and doesn\'t match \'/pants or /shoes\' for coupon2.
在 ActiveRecord 中测试这些很容易。这里只是示例 1。
@url = \'/hats\'
@query = coupon1.query
# \"\'/hats\' = :url\"
Coupon.where(@query, url: @url).count
=> 2
# count is non-zero number because the query matches the url parameter.
# Coupon1 passes, its id would be returned from the stored procedure.
\'/hats\' == \'/hats\'
@query = coupon2.query
# \" \'/pants\' = :url OR \'/shoes\' = :url \"
Coupon.where(@query, url: @url).count
=> 0
# count is 0 because the query does not match the url parameter.
# Coupon2 does not pass, its id would not be returned from the stored procedure.
\'/pants\' != \'/hats\', \'/shoes\' != \'/hats\'
你可以把它写成一个循环(我在 ruby on rails with activerecord),但我需要一些性能更好的东西——我可能有很多优惠券,所以我不能直接用循环检查每一张。查询包含复杂的 AND/OR 逻辑,因此我也不能只与 url 列表进行比较。但这里有一些循环代码,本质上是我试图将其转换为存储过程。
# assume coupon1 has id 1, coupon2 has id 2
@coupons = [coupon1, coupon2]
@url = \'/hats\'
@coupons.map do |coupon|
if Coupon.where(coupon.query, url: @url).count > 0
coupon.id
else
nil
end
end
=> [1, nil]
-
这是一个奇怪的用例。为什么要保存 \" \'/hats\' = :url \" 而不仅仅是 \'/hats\'?
标签: mysql ruby-on-rails stored-procedures dynamic-sql