Je veux exécuter une mise à jour de sql brut comme ci-dessous:
update table set f1=? where f2=? and f3=?
Ce SQL sera exécuté par ActiveRecord::Base.connection.execute
, mais je ne sais pas comment passer les valeurs des paramètres dynamiques dans la méthode.
Quelqu'un pourrait-il m'aider à ce sujet?
ruby-on-rails
activerecord
rawsql
Ywenbo
la source
la source
Réponses:
Il ne semble pas que l'API Rails expose des méthodes pour le faire de manière générique. Vous pouvez essayer d'accéder à la connexion sous-jacente et d'utiliser ses méthodes, par exemple pour MySQL:
Je ne sais pas s'il y a d'autres ramifications à faire cela (connexions laissées ouvertes, etc.). Je tracerais le code Rails pour une mise à jour normale pour voir ce qu'il fait en dehors de la requête réelle.
L'utilisation de requêtes préparées peut vous faire gagner un peu de temps dans la base de données, mais à moins que vous ne le fassiez un million de fois de suite, vous feriez probablement mieux de simplement créer la mise à jour avec une substitution Ruby normale, par exemple
ou en utilisant ActiveRecord comme l'ont dit les commentateurs.
la source
field=#{value}
car elle vous laisse grand ouvert aux attaques par injection SQL. Si vous suivez ce chemin, consultez le module ActiveRecord :: ConnectionAdapters :: Quoting .prepare
déclaration dans Mysql2execute
est une méthode dangereuse et peut provoquer des fuites de mémoire ou d'autres ressources.ActiveRecord::Base.connection
a unequote
méthode qui prend une valeur de chaîne (et éventuellement l'objet de colonne). Vous pouvez donc dire ceci:Notez que si vous êtes dans une migration Rails ou un objet ActiveRecord, vous pouvez raccourcir cela en:
MISE À JOUR: comme @kolen le souligne, vous devriez utiliser à la
exec_update
place. Cela gérera les citations pour vous et évitera également les fuites de mémoire. La signature fonctionne un peu différemment cependant:Ici, le dernier paramètre est un tableau de tuples représentant les paramètres de liaison. Dans chaque tuple, la première entrée est le type de colonne et la seconde est la valeur. Vous pouvez
nil
indiquer le type de colonne et Rails fera généralement la bonne chose.Il existe également
exec_query
,exec_insert
etexec_delete
, en fonction de vos besoins.la source
execute
est une méthode dangereuse et peut provoquer des fuites de mémoire ou d'autres ressources.on duplicate key update
ON CONFLICT DO UPDATE
si vous le souhaitez. Pour le SQL non brut, ce joyau semble pratique: github.com/jesjos/active_record_upsertVous devriez simplement utiliser quelque chose comme:
Cela ferait l'affaire. Utiliser la méthode ActiveRecord :: Base # send pour invoquer sanitize_sql_for_assignment fait que Ruby (au moins la version 1.8.7) ignore le fait que sanitize_sql_for_assignment est en fait une méthode protégée.
la source
Parfois, il serait préférable d'utiliser le nom de la classe parente au lieu du nom de la table:
Par exemple, classe de base "Personne", sous-classes (et tables de base de données) "Client" et "Vendeur" à la place en utilisant:
Vous pouvez utiliser l'objet de la classe de base de cette manière:
la source
Pourquoi utiliser du SQL brut pour cela?
Si vous avez un modèle à utiliser
where
:Si vous n'avez pas de modèle pour cela (juste la table), vous pouvez créer un fichier et un modèle qui hériteront de
ActiveRecord::Base
et utilisez à nouveau
where
la même chose que ci-dessus:la source
Voici une astuce que j'ai récemment élaborée pour exécuter SQL brut avec des liaisons:
où
ApplicationRecord
définit ceci:et cela est similaire à la façon dont AR lie ses propres requêtes.
la source
J'avais besoin d'utiliser raw sql car je n'avais pas réussi à faire fonctionner composite_primary_keys avec activerecord 2.3.8. Ainsi, pour accéder à la table sqlserver 2000 avec une clé primaire composite, un sql brut était requis.
Si une meilleure solution est disponible, veuillez la partager.
la source
Dans Rails 3.1, vous devez utiliser l'interface de requête:
update et update_all sont l'opération dont vous avez besoin.
Voir les détails ici: http://m.onkey.org/active-record-query-interface
la source