2

Я пытаюсь использовать exec_query для запуска произвольного запроса со значениями, введенными через привязки, и я получаю непредвиденные ошибки.Rails exec_query bindings ignored

Запуск этого в консоли

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/[email protected]_project/gems/activerecord-4.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:641:in `prepare'

Он появляется синтаксис привязки игнорируется? Я тоже пробовал ... WHERE id = ?, но безрезультатно.

+0

'exec_query' является частью интерфейса драйвера низкого уровня, поэтому вы должны использовать собственные заполнители базы данных в случае PostgreSQL, который будет' $ 1', '$ 2', ... Как только вы закончите, вы, вероятно, столкнулись с «NoMethodError», потому что «binds» - это не то, что ожидается; Я не знаю, как будет выглядеть «привязка», поскольку ни один из этих материалов не документирован, а код, стоящий за ним, является обычным непостижимым недостатком, который вы находите внутри Rails. –

ответ

2

mu слишком коротко, вы попали в путь. Для справки, вот документация метода: https://apidock.com/rails/ActiveRecord/ConnectionAdapters/DatabaseStatements/exec_query

Он прав в том, что вам нужно будет использовать синтаксис привязки базовой базы данных для установки переменных связывания в строке SQL. Для Oracle это :1, :2 для PostgreSQL, это $1, $2..., так что это первый шаг.

Шаг два это вам нужно построить BIND объекты, которые являются объектами QueryAttribute, а не только значения, которые передаются в этом немного неуклюжим, но вот пример:. binds = [ActiveRecord::Relation::QueryAttribute.new("id", 6, ActiveRecord::Type::Integer.new)] ApplicationRecord.connection.exec_query('select * from users where id = $1', 'sql', binds)

Я просто провел весь день проходит модульные тесты и исходный код, пытаясь понять это.

+0

Спасибо, что пошёл на все эти неприятности. Доступ к базе данных в Ruby довольно ужасен, когда вы выходите за пределы обычных ящиков. –

+0

Ничего страшного, я тоже должен был разобраться в своих вещах. Я был просто удивлен, как трудно было сделать что-то, что должно было быть так просто. По крайней мере, на oracle_enhanced, на самом деле проще просто использовать базовый адаптер OCI8. – Michael