6

今私はSQLiteからPostgresqlへの移行の途中ですが、この問題を遭遇しました。以下のプリペアドステートメントは、SQLiteので動作します:PostgreSQLのRailsでの準備文

id = 5 
st = ActiveRecord::Base.connection.raw_connection.prepare("DELETE FROM my_table WHERE id = ?") 
st.execute(id) 
st.close 

は、残念ながらそれは、PostgreSQLで動作していない - それは私が解決策を探していたライン2 で例外をスローし、この出くわし:

id = 5 
require 'pg' 
conn = PG::Connection.open(:dbname => 'my_db_development') 
conn.prepare('statement1', 'DELETE FROM my_table WHERE id = $1') 
conn.exec_prepared('statement1', [ id ]) 

このこの

rescue => ex 

exはこの

が含まれているように、私は例外を印刷するとき1行3で失敗します
{"connection":{}} 

SQLをコマンドラインで実行すると機能します。私が間違って何をしているのか?

ありがとうございます!

+0

どうすればわかりますか?私は例外に関してコンソールに出力がないので尋ねています。 –

答えて

20

あなたがそのようなprepareを使用したい場合、あなたはカップルの変更を加える必要があります:

  1. PostgreSQLのドライバは疑問符ないの番号のプレースホルダ($1$2、...)を見たいですそして、あなたのプリペアドステートメントの名前を与える必要があります。

    ActiveRecord::Base.connection.raw_connection.prepare('some_name', "DELETE FROM my_table WHERE id = $1") 
    
  2. 呼び出しシーケンスは、exec_preparedによってprepare続きます。

    connection = ActiveRecord::Base.connection.raw_connection 
    connection.prepare('some_name', "DELETE FROM my_table WHERE id = $1") 
    st = connection.exec_prepared('some_name', [ id ]) 
    

上記のアプローチは、ActiveRecordのとPostgreSQLとの私のために働くあなたが適切に接続している場合は、あなたのPG::Connection.openバージョンが動作するはずです。

もう一つの方法は、引用符を自分で行うことです。

conn = ActiveRecord::Base.connection 
conn.execute(%Q{ 
    delete from my_table 
    where id = #{conn.quote(id)} 
}) 

ActiveRecordのは、通常、あなたの背中の後ろにやっているものの一種だこと。

Railsの人々はあなたがそれをやるべきだとは思わないので、データベースと直接対話するのは、Railsのちょっとした混乱になりがちです。

あなたが本当にちょうどあなたがdeleteを使用することができ、干渉せずに行を削除しようとしている場合:

(削除)

[...]

行は単純ですレコードの主キーのSQL DELETEステートメントで削除され、コールバックは実行されません。

MyTable.delete(id) 

を、あなたは、データベースに簡単なdelete from my_tables where id = ...をお送りします:

だから、ちょうどこれを言うことができます。

+0

あなたは文章に名前を付け、疑問符の代わりにドルの文字を使用していました。私は削除機能を認識しています - この場合、自分のモデルを持っていないジョイントテーブルから何かを削除しています。 1つを作成するのではなく、私は「クイック」な解決策に出かけました。ありがとう! –