2011-11-18 42 views
14

içinde tek bir tırnaktan kaçma name ve address adında iki sütun içeren bir tablo companies var. Aşağıdaki kodu çalıştırarak, yeni veri tabloya eklenir: Ben "John's company" için "my company name" den my_name değerini değiştirirsenizSQL sorgusunda

my_name = "my company name" 
my_address = "ABC" 

query = "INSERT INTO companies (name,address) VALUES ('#{my_name}','#{my_address}');" 

ActiveRecord::Base.connection.execute(query); 

, bir sözdizimi hatası alırsınız.

"INSERT INTO companies (name,address) VALUES ('John's company','ABC');" 

ve 'John's company' bunun içinde tek bir soru işareti bulunan: Sorgu olur olmasıdır.

Sorgu dizesi tanımlaması için zaten çift tırnak işareti kullandım, bu hatadan, değerindeki tek tırnak işareti ile nasıl kurtulabilirim?

+0

bir \ ile kaçmak? – rgin

+0

my_name.include? ('\' ') My_name.sub (/' /, '\' ')? –

+3

Bu gerçekten kötü bir fikir ... ters eğik çizgilerle tek tırnaktan kaçsanız bile SQL enjeksiyon saldırılarını riske atıyorsunuz. Karakter kodlamalarını anlamanız gerekir, ancak bu naif yaklaşımın ciddi (bilinen) bir istisnası vardır. Sorgunuzda bağlama parametrelerini kullanın ve DBMS'nin değerleri güvenli bir şekilde taşımasına izin verin. – d11wtq

cevap

61

bunu daha sonra bağlantı nesnede quote method kullanmak bu şekilde yapmanız gerekir:

alıntı (değer, sütun = nil)
SQL enjeksiyon saldırıları önlemeye yardımcı olmak için sütun değerini Alıntılar.

böyle Yani bir şey:

my_name = ActiveRecord::Base.connection.quote("John O'Neil") 
my_address = ActiveRecord::Base.connection.quote("R'lyeh") 

query = "INSERT INTO companies (name,address) VALUES (#{my_name}, #{my_address})" 

ActiveRecord::Base.connection.execute(query); 

hiç kendi alıntı işlemek kalkma. Ve bir SQL dizgisi literalini alıntılamak için çift tırnak kullanmayı denemeyin, tek tırnaklar bunun içindir; çift ​​tırnak, çoğu veritabanında tanımlayıcıları (tablo ve sütun adları gibi) alıntılamak içindir, ancak MySQL bunun için backticks kullanır.

+0

my_name için değişken kullanıyorum, sanırım kullanabiliyorum my_name = ActiveRecord :: Base.connection.quote (NAME_VARIABLE) –

+0

@ Leem.fin: Right. Ya da dize enterpolasyonunun içine koyabilirsiniz ama bu kodunuzun okunmasını zorlaştırabilir. –

+0

Kodunuzda bir hata olduğunu düşünüyorum, quote() yöntemi zaten dize için tırnak işareti eklediğinden VALUES kısmındaki tek tırnak işaretini kaldırmanız gerekir. Şimdi, eğer kodu çalıştırdığınız gibi çalıştırırsam, '' John'un şirketini '' –

İlgili konular