现在我正在从SQLite迁移到Postgresql,我遇到了这个问题。以下准备好的语句适用于SQLite:
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
ex包含此
{"connection":{}}
在命令行中执行SQL有效。知道我做错了什么吗?
提前致谢!
答案 0 :(得分:24)
如果您想使用prepare
,那么您需要进行一些更改:
PostgreSQL驱动程序希望看到编号占位符($1
,$2
,...)不是问号,您需要为准备好的语句命名:
ActiveRecord::Base.connection.raw_connection.prepare('some_name', "DELETE FROM my_table WHERE id = $1")
调用序列为prepare
,后跟exec_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 = ...
。