I have a table called Coupon
.
This table has a column called query
which holds a string.
The query
string has some logical conditions in it formatted for a where
statement. For example:
coupon1.query
=> " '/hats' = :url "
coupon2.query
=> " '/pants' = :url OR '/shoes' = :url "
I want to write a stored procedure that takes as input 2 parameters: a list of Coupon
ids and a variable (in this example, the current URL).
I want the procedure to look up the value of the query
column from each Coupon
. Then it should run that string in a where
statement, plugging in my other parameter (current url), then return any Coupon
ids that matches.
Here's how I would expect the procedure to behave given the two coupons above.
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.
It's easy to test these out in ActiveRecord. Here is just example 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'
You could write this as a loop (I'm in ruby on rails with activerecord) but I need something that performs better - I could potentially have lots of coupons so I can't just check each one directly with a loop. The queries contain complex AND/OR logic so I can't just compare against a list of urls either. But here's some code of a loop that is essentially what I'm trying to translate into a stored procedure.
# 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]