在where子句中验证SQL

时间:2013-06-04 01:00:09

标签: ruby-on-rails activerecord

我有一种情况需要允许从表单手动构建SQL。我有这样的事情:

SomeModel.where("id in (#{custom_sql})")

其中custom_sql是一个select语句,如下所示:

SELECT u.id FROM some_model u WHERE country_iso = 'AU'

我希望能够捕获where子句中存在无效SQL时抛出的StatementInvalid异常,但我无法弄清楚如何执行此操作。

begin
  SomeModel.where("id in (#{custom_sql})")  
rescue 
  puts "Error"
end

但它一直没有出错。但是在rails c中,当我执行User.where("id in (#{custom_sql})")时,它会正确错误。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

使用ActiveRecord::Base.connection.execute检查SQL语句的有效性。如果您的陈述无效,则会抛出错误。

begin
  ActiveRecord::Base.connection.execute custom_sql
  User.where("id in (#{custom_sql})")  
rescue 
  puts "Error"
end

答案 1 :(得分:1)

首先,您的示例不清楚或具有误导性(可能是因为您努力掩盖您的实际型号名称)

因为如果您真的想要运行您提出的方案,那么您的结果查询将是

select * from some_model where id in (select u.id from some_model u where country_iso = "AU"

(忽略你的country_iso字段不明确的事实)你刚刚开始

SomeModel.where country_iso: "AU"

因此,您需要优化您的示例并正确说明您的问题,因为虽然@zeantsoi建议了一种方法来帮助您验证您的陈述,但我同意@phoet您可能错误地接近了这种情况。

答案 2 :(得分:0)

首先,这是sql注入最好的。你应该重新考虑你想要完成的任何事情。

其次,User.where返回一个关系。关系是懒惰的。懒惰的语句尚未执行。所以,如果你正在做User.where(...).all这应该有所帮助。