如何在不使用where()方法的情况下准备SQL语句

时间:2014-05-23 03:48:31

标签: sql ruby-on-rails

有没有办法准备像ActiveRecord where()方法构建的SQL语句(使用命名占位符):

Client.where("created_at >= :start_date AND created_at <= :end_date",
{start_date: params[:start_date], end_date: params[:end_date]})  

我必须在CASE .. END子句之后的ORDER BY语句中使用它(或在SELECT中创建计算列)以保护它免受SQL注入。

修改
我也必须通过此查询检索所有ActiveRecord模型。我可以使用find_by_sql()吗? (试...)。

EDIT2 find_by_sql()无法在上面的代码示例中使用命名占位符(:start_date)。

它的Rails 3.2.11

EDIT3
抱歉,它可以与数组一起用作一个参数(find_by_sql with array format in Rails 3)。

2 个答案:

答案 0 :(得分:1)

是的,您可以编写/准备ActiveRecord所做的任何事情。您的意思是使用直接DBI查询吗?

我建议您跟踪ActiveRecord正在生成的SQL。

Retrieving sql queries from Active-record queries in Rails 3

Tracing Rails 3 SQL queries

http://guides.rubyonrails.org/v2.3.11/debugging_rails_applications.html

请参阅query_trace了解一种方法。

关于如何使用Ruby DBI和预处理语句的教程:

http://www.tutorialspoint.com/ruby/ruby_database_access.htm

直接从教程中引用:

#!/usr/bin/ruby -w

require "dbi"

begin
 # connect to the MySQL server
 dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", 
                    "testuser", "test123")
 sth = dbh.prepare( "INSERT INTO EMPLOYEE(FIRST_NAME,
               LAST_NAME, 
               AGE, 
       SEX, 
       INCOME)
               VALUES (?, ?, ?, ?, ?)" )
 sth.execute('John', 'Poul', 25, 'M', 2300)
 sth.execute('Zara', 'Ali', 17, 'F', 1000)
 sth.finish
 dbh.commit
 puts "Record has been created"
rescue DBI::DatabaseError => e
 puts "An error occurred"
 puts "Error code:    #{e.err}"
 puts "Error message: #{e.errstr}"
 dbh.rollback
ensure
 # disconnect from server
 dbh.disconnect if dbh
end

答案 1 :(得分:0)

使用find_by_sql()解决了这个问题。

但是这不能用作范围查询。 (因而无法链接)。