现在我正在从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可以工作。知道我做错了什么吗?
先谢了!
2条答案
按热度按时间huwehgph1#
如果您想像这样使用
prepare
,那么您需要做一些更改:$1
,$2
,...)而不是问号,您需要为预准备语句命名:1.调用序列为
prepare
,后跟exec_prepared
:上面的方法对我来说适用于ActiveRecord和PostgreSQL,如果你连接正确,你的
PG::Connection.open
版本应该可以工作。另一种方法是自己引用:
这就是ActiveRecord通常在你背后做的事情。
直接与数据库交互往往会给Rails带来一些麻烦,因为Rails人员认为您永远不应该这样做。
如果您真的只想删除一行而不产生干扰,可以使用
delete
:[...]
只需对记录的主键使用SQL
DELETE
语句删除该行,并且不执行回调。所以你可以这么说:
然后将一个简单的
delete from my_tables where id = ...
发送到数据库中。uelo1irk2#
为了补充一个已经被接受的答案,任何人在Rails中搜索预准备语句进行自定义查询,这里有一个更简单的方法,通过现有的ActiveRecord接口(例如Postgresql):
如果输入
binding.pry
,您将看到预准备语句确实已创建:参考:https://api.rubyonrails.org/v7.0.4.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html