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...

Postgresql9.2とrails3.2の使用

私がここで見つけた代替ソリューションを追加して編集します:

muがconnection.method(:quote)を使用する場所では短すぎることに加えて、ドキュメントが見つからなかったため、引用がそのように行われた別の投稿に出くわしました。

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

1 に答える 1

1

細かい(?)マニュアルから:

execute(sql、name = nil)

SQLステートメントを実行し、成功するとPGresultオブジェクトを返すか、それ以外の場合はPGError例外を発生させます。

2番目のパラメーターは、パラメーターをバインドするためのものではなく、(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内の整数にキャストします)。

または、 raw pgインターフェースを使用してデータベースに接続し、実際に準備されたステートメントを使用します。

于 2013-03-25T23:19:51.053 に答える