2012-03-28 17 views
14

Ho provato a utilizzare google per rispondere a questa domanda apparentemente semplice, ma con mia sorpresa, non è stato d'aiuto.Come si creano istruzioni preparate con la gemma mysql2?

Ho il codice nella mia applicazione rails che attualmente utilizza il metodo "prepare" con mysql gem. Sul passaggio a mysql2, questo si rompe con l'errore:

undefined method `prepare' for #<Mysql2::Client::0....... 

così ho provato alla ricerca di una versione del metodo 'preparare', ma questa ricerca è rimasta soccombente finora. Qualcuno può aiutarmi con questo?

Modifica: Se questo non è possibile, qualcuno potrebbe farmi sapere se c'è un modo per parametrizzare semplicemente le mie query con qualcosa nella libreria mysql2?

risposta

5

Il mysql2 gemma ora supporta le istruzioni preparate secondo la documentation.

La sintassi è la seguente:

statement = @client.prepare("SELECT * FROM users WHERE login_count = ?") 
result1 = statement.execute(1) 
result2 = statement.execute(2) 

Questa era added con una richiesta di pull fusione nel giugno 2015.

+1

Finalmente! Ci sono voluti solo pochi anni. – Nikhil

+0

Questo supporto è in mysql2 da 0.4.0+ –

14

UPDATE

Come Ryan Rapp rilevare correttamente, mysql2 ora supporta le istruzioni preparate. Seguente frammento viene estratto dal readme:

statement = @client.prepare("SELECT * FROM users WHERE login_count = ?") 
result1 = statement.execute(1) 
result2 = statement.execute(2) 

statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?") 
result = statement.execute(1, "CA") 

Grazie Ryan!

originale Messaggio

ho trovato nessuna tale funzione sia; né in source né nello documentation. Forse lo snippet seguente è un utile sostituto per le tue esigenze? (Che si trova nella documentazione di mysql2 gemma):

escaped = client.escape("gi'thu\"bbe\0r's") 
results = client.query("SELECT * FROM users WHERE group='#{escaped}'") 
+0

speravo in un modo per utilizzare le query parametrizzate come se fossi in precedenza. "seleziona * dal mio tavolo dove mycolumn1 =?" e così via. Incrocio le dita per trovare qualcosa del genere. – Nikhil

+0

Accettato perché non c'è modo di farlo fuori dalla scatola. Finito per avvolgerlo con un record attivo usato fuori dalle rotaie nel mio script rubino. Grazie. – Nikhil

+15

incredibilmente deludente per una moderna interfaccia di database che non supporta query parametrizzate – wmarbut

3

Ho scambiato da usare al posto di https://github.com/tmtm/ruby-mysql mysql2. Sono sorpreso che questo non sia un grande affare per chi usa la gemma mysql2. Immagino che le persone che hanno approfondito questo argomento nella scrittura di SQL si siano scambiati con Postgresql?

Nel caso in cui gli altri stanno avendo problemi con gem install ruby-mysql seguita da require "mysql" in cui si ottiene un errore di Rubino come 'read_eof_packet': packet is not EOF (Mysql::ProtocolError) il trucco è quello di gem uninstall ruby-mysql e invece gem install ruby-mysql-ext (o utilizzare gem 'ruby-mysql-ext' nel vostro Gemfile) che scambiare l'implementazione di Ruby, che non è ancora compatibile con Ruby 2.0 (o almeno, non ha funzionato per me) per semplici collegamenti C.

Per essere chiari, se si esegue require 'mysql' mentre sono installati sia ruby-mysql-ext e ruby-mysql, verrà caricata la versione di Ruby. Potrebbe esserci un modo per richiedere un gioiello specifico, ma non ho avuto il tempo di cercarlo.

0

Sono anche sorpreso che manchi il metodo di preparazione. Sicuramente in una comune configurazione di ActiveRecord e Mysql2, ActiveRecord deve eseguire l'escape delle stringhe piuttosto che usare libmysql, che trovo un po 'preoccupante.

Nel frattempo, è possibile utilizzare https://github.com/brianmario/mysql2/tree/stmt

0

Rails e l'adattatore attivo record di MySQL non ha il supporto per le istruzioni preparate per quanto ne so:

http://patshaughnessy.net/2011/10/22/show-some-love-for-prepared-statements-in-rails-3-1

Questo perché in realtà non ha alcun utilizzo nelle dichiarazioni di accelerazione e può effettivamente rallentare le cose a causa della mancanza di pianificazione delle query di MySQL.

+0

Non sono sicuro che questo sia più vero (o forse anche allora!) Dato che devi attivare manualmente le istruzioni preparate sul lato server, per impostazione predefinita è disattivato. Vedi questa e altre impostazioni su https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration –

1

Sì, l'adattatore mysql2 non supporta il binding fino all'attuale Rails 4.0. Sono sorpreso! Si potrebbe dire questo per il codice di snip da ~/.rvm/gemme/ruby-2.1.1/gemme/activerecord-4.1.1/lib/active_record/connection_adapters/mysql2_adapter.rb

 def exec_query(sql, name = 'SQL', binds = []) 
     result = execute(sql, name) 
     ActiveRecord::Result.new(result.fields, result.to_a) 
     end 

     alias exec_without_stmt exec_query 

     # Returns an ActiveRecord::Result instance. 
     def select(sql, name = nil, binds = [])                              
     exec_query(sql, name) 
     end 

anche questo è utile per voi la comprensione:

(in ~/.rvm/gemme/ruby-2.1.1/gemme/activerecord-4.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb)

 # Returns an ActiveRecord::Result instance. 
     def select_all(arel, name = nil, binds = []) 
     if arel.is_a?(Relation) 
      relation = arel 
      arel = relation.arel                                  
      if !binds || binds.empty? 
      binds = relation.bind_values 
      end 
     end 

     select(to_sql(arel, binds), name, binds) 
     end 

Questo è tutto! E credo che potrei rivolgermi a Postgres !!

Problemi correlati