我正在尝试使用exec_query
来运行任意查询,并通过绑定引入值,并且会出现意外错误。
在控制台中运行
sql = 'SELECT * FROM foobars WHERE id IN (?)'
name = 'query_name_placeholder'
binds = [FooBar.first]
ActiveRecord::Base.connection.exec_query sql, name, binds
产生此错误:
Account Load (7.9ms) SELECT "foobars".* FROM "foobars" ORDER BY "foobars"."id" ASC LIMIT 1
PG::SyntaxError: ERROR: syntax error at or near ")"
LINE 1: SELECT * FROM foobars WHERE id IN (?)
^
: SELECT * FROM foobars WHERE id IN (?)
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near ")"
LINE 1: SELECT * FROM foobars WHERE id IN (?)
^
: SELECT * FROM accounts WHERE id IN (?)
from /Users/foo_user/.rvm/gems/ruby-2.2.4@foo_project/gems/activerecord-4.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:641:in `prepare'
似乎忽略了绑定语法?我也尝试了... WHERE id = ?
,但无济于事。
答案 0 :(得分:5)
mu太短了让你在那里的一部分。作为参考,这是方法的文档:https://apidock.com/rails/ActiveRecord/ConnectionAdapters/DatabaseStatements/exec_query
他说得对,你需要使用底层数据库的绑定语法在SQL字符串中设置绑定变量。对于Oracle,对于PostgreSQL来说这是$1, $2...
,这是binds = [ ActiveRecord::Relation::QueryAttribute.new(
"id", 6, ActiveRecord::Type::Integer.new
)]
ApplicationRecord.connection.exec_query(
'SELECT * FROM users WHERE id = $1', 'sql', binds
)
所以这是第一步。
第二步是你需要构建绑定对象,它们是QueryAttribute对象,而不仅仅是要传入的值。这有点笨重,但这是一个例子:
{{1}}
我只花了一整天时间进行单元测试和源代码试图解决这个问题。