Я хочу выполнить одно обновление raw sql, как показано ниже:
update table set f1=? where f2=? and f3=?
Этот SQL будет выполняться ActiveRecord::Base.connection.execute
, но я не знаю, как передать значения динамических параметров в метод.
Может ли кто-нибудь помочь мне в этом?
ruby-on-rails
activerecord
rawsql
Ywenbo
источник
источник
Ответы:
Не похоже, что Rails API предоставляет общие методы для этого. Вы можете попробовать получить доступ к базовому соединению и использовать его методы, например, для MySQL:
Я не уверен, есть ли у этого другие последствия (соединения остаются открытыми и т. Д.). Я бы проследил код Rails для обычного обновления, чтобы увидеть, что он делает помимо фактического запроса.
Использование подготовленных запросов может сэкономить вам небольшое количество времени в базе данных, но если вы не делаете это миллион раз подряд, вам, вероятно, будет лучше просто создать обновление с обычной заменой Ruby, например
или с помощью ActiveRecord, как сказали комментаторы.
источник
field=#{value}
поскольку это оставляет вас открытыми для атак SQL-инъекций. Если вы пойдете по этому пути, проверьте модуль ActiveRecord :: ConnectionAdapters :: Quoting .prepare
заявления в Mysql2execute
является опасным методом и может вызвать утечку памяти или других ресурсов.ActiveRecord::Base.connection
имеетquote
метод, который принимает строковое значение (и, возможно, объект столбца). Итак, вы можете сказать это:Обратите внимание, если вы выполняете миграцию Rails или объект ActiveRecord, вы можете сократить это до:
ОБНОВЛЕНИЕ: как указывает @kolen, вы должны использовать
exec_update
вместо этого. Это обработает цитирование за вас, а также предотвратит утечку памяти. Однако подпись работает немного иначе:Здесь последний параметр - это массив кортежей, представляющих параметры привязки. В каждом кортеже первая запись - это тип столбца, а вторая - значение. Вы можете
nil
указать тип столбца, и Rails обычно поступает правильно.Есть также
exec_query
,exec_insert
иexec_delete
, в зависимости от того, что вам нужно.источник
execute
является опасным методом и может вызвать утечку памяти или других ресурсов.on duplicate key update
вездеON CONFLICT DO UPDATE
если хотите. Для не-сырого SQL этот гем выглядит удобно: github.com/jesjos/active_record_upsertВы должны просто использовать что-то вроде:
Это поможет. Использование метода ActiveRecord :: Base # send для вызова sanitize_sql_for_assignment заставляет Ruby (по крайней мере, версия 1.8.7) пропускать тот факт, что sanitize_sql_for_assignment на самом деле является защищенным методом.
источник
Иногда было бы лучше использовать имя родительского класса вместо имени таблицы:
Например, базовый класс «Человек», подклассы (и таблицы базы данных) «Клиент» и «Продавец» Вместо использования:
Вы можете использовать объект базового класса следующим образом:
источник
Зачем использовать для этого необработанный SQL?
Если у вас есть модель, используйте
where
:Если у вас нет модели для него (только таблица), вы можете создать файл и модель, которые будут унаследованы от
ActiveRecord::Base
и снова используйте
where
то же, что и выше:источник
Вот трюк, который я недавно разработал для выполнения необработанного sql с привязками:
где
ApplicationRecord
это определяется:и это похоже на то, как AR связывает свои собственные запросы.
источник
Мне нужно было использовать raw sql, потому что мне не удалось заставить композитный_primary_keys работать с activerecord 2.3.8. Поэтому для доступа к таблице sqlserver 2000 с составным первичным ключом требовался необработанный sql.
Если доступно лучшее решение, поделитесь.
источник
В Rails 3.1 вы должны использовать интерфейс запросов:
update и update_all - необходимые вам операции.
Подробности смотрите здесь: http://m.onkey.org/active-record-query-interface
источник