1
ActiveRecord::Base.connection.execute(
          "WITH numberofdays AS 
          (SELECT percent_change FROM asset_histories 
          WHERE date < $1
          AND asset_symbol = $2
          ORDER BY date DESC
          LIMIT $3)
          SELECT stddev_samp(percent_change) as stdev FROM numberofdays",
          [day,symbol,daystolimit])

其中 day、symbol 和 daystolimit 是在上述代码之前分配的变量。它们是这样分配的:

day = '2013-03-25'
symbol = 'AAPL'
daystolimit = 20

我不想使用#{variable},因为可能存在恶意。如标题所述,我的声明正在返回

PGError ERROR: there is no parameter $1 LINE 1 ... WHERE date <$1 AND...

使用 Postgresql 9.2 和 rails 3.2

编辑添加我在这里找到的替代解决方案:

除了 mu 在他使用 connection.method(:quote) 的地方太短之外,我找不到关于它的文档,所以我遇到了另一篇这样引用的帖子:

a = ActiveRecord::Base.connection
a.execute(%Q{SELECT * FROM table WHERE id = #{a.quote(variable)}...})
4

1 回答 1

1

罚款(?)手册

执行(sql,名称 = nil)

执行 SQL 语句,成功时返回 PGresult 对象,否则引发 PGError 异常。

请注意,第二个参数不是用于绑定参数,它是(AFAIK)日志记录目的的名称。

ActiveRecord 实际上并没有在内部使用绑定参数,它只是自己进行引用和转义,并为数据库构建一个大的 SQL 字符串(cringe)。quote您可以使用方法和字符串插值来模仿这种行为:

q = ActiveRecord::Base.connection.method(:quote)
ActiveRecord::Base.connection.execute(%Q{
    WITH numberofdays AS 
    (SELECT percent_change FROM asset_histories 
    WHERE date < #{q[day]}
    AND asset_symbol = #{q[symbol]}
    ORDER BY date DESC
    LIMIT #{daystolimit})
    SELECT stddev_samp(percent_change) as stdev FROM numberofdays
})

您必须自己确保这daystolimit是一个数字(或者也引用它并在 SQL 中转换为整数)。

或者,使用原始 pg接口连接到数据库并使用实际准备好的语句。

于 2013-03-25T23:19:51.053 回答