6

現在我正在從SQLite遷移到Postgresql,我遇到了這個問題。下面準備好的聲明可以用於任何: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 ]) 

這在第3行一個失敗,當我打印這樣

rescue => ex 

前的異常包含此

{"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. 調用序列之後prepareexec_prepared

    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

你是對的 - 給這個陳述一個名字,用一個美元字符而不是問號做這個工作。我知道刪除功能 - 在這種情況下,我正在從沒有自己的模型的聯合表中刪除一些東西。我創造了一個「快速」解決方案,而不是創建一個。謝謝! –