110

以下のように1つの更新生SQLを実行したい:

update table set f1=? where f2=? and f3=?

この SQL は によって実行されますがActiveRecord::Base.connection.execute、動的パラメータ値をメソッドに渡す方法がわかりません。

誰か助けてくれませんか?

4

8 に答える 8

110

Rails API がこれを一般的に行うためのメソッドを公開しているようには見えません。基礎となる接続にアクセスして、そのメソッドを使用してみることができます (たとえば、MySQL の場合)。

st = ActiveRecord::Base.connection.raw_connection.prepare("update table set f1=? where f2=? and f3=?")
st.execute(f1, f2, f3)
st.close

これを行うことに他の影響があるかどうかはわかりません(接続が開いたままになるなど)。通常の更新の Rails コードをトレースして、実際のクエリとは別に、Rails が何をしているのかを確認します。

準備されたクエリを使用すると、データベースでの時間を少し節約できますが、これを何百万回も続けて行う場合を除き、通常の Ruby 置換を使用して更新をビルドする方がよいでしょう。

ActiveRecord::Base.connection.execute("update table set f1=#{ActiveRecord::Base.sanitize(f1)}")

または、コメント作成者が言ったように ActiveRecord を使用します。

于 2010-12-19T18:54:20.523 に答える
37

ActiveRecord::Base.connectionquote文字列値 (およびオプションで列オブジェクト) を取るメソッドがあります。したがって、次のように言えます。

ActiveRecord::Base.connection.execute(<<-EOQ)
  UPDATE  foo
  SET     bar = #{ActiveRecord::Base.connection.quote(baz)}
EOQ

Rails 移行または ActiveRecord オブジェクトを使用している場合は、次のように短縮できます。

connection.execute(<<-EOQ)
  UPDATE  foo
  SET     bar = #{connection.quote(baz)}
EOQ

更新: @kolen が指摘するように、exec_update代わりに使用する必要があります。これにより、引用が処理され、メモリリークも回避されます。ただし、署名の動作は少し異なります。

connection.exec_update(<<-EOQ, "SQL", [[nil, baz]])
  UPDATE  foo
  SET     bar = $1
EOQ

ここで最後の param は、バインド パラメータを表すタプルの配列です。各タプルで、最初のエントリは列の型で、2 番目のエントリは値です。列の型を指定することはできますがnil、Rails は通常正しいことを行います。

必要に応じてexec_queryexec_insert、 、もあります。exec_delete

于 2014-07-01T23:01:35.380 に答える
4

次のようなものを使用する必要があります。

YourModel.update_all(
  ActiveRecord::Base.send(:sanitize_sql_for_assignment, {:value => "'wow'"})
)

それはトリックを行うでしょう。ActiveRecord::Base#sendメソッドを使用してsanitize_sql_for_assignmentを呼び出すと、Ruby (少なくとも 1.8.7 バージョン) は、sanitize_sql_for_assignmentが実際には保護されたメソッドであるという事実をスキップします。

于 2012-05-15T03:12:50.763 に答える
-22

Rails 3.1では、クエリインターフェイスを使用する必要があります。

  • new(属性)
  • create(属性)
  • create!(属性)
  • find(id_or_array)
  • destroy(id_or_array)
  • destroy_all
  • delete(id_or_array)
  • すべて削除
  • update(ids、updates)
  • update_all(updates)
  • 存在しますか?

updateとupdate_allは、必要な操作です。

詳細はこちらをご覧ください:http://m.onkey.org/active-record-query-interface

于 2011-11-11T09:40:04.980 に答える