2011-11-18 108 views
14

內的單引號我有一個表companies,其中有一個名爲nameaddress兩列。通過運行下面的代碼,新的數據被插入到表:擺脫SQL查詢

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

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

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

如果我改變從"my company name""John's company"my_name價值,我會得到一個語法錯誤。這是因爲查詢變爲:

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

'John's company'中有一個單引號。

既然我已經用於查詢字符串定義雙引號,我怎樣才能得到關於我的價值,單引號去掉這個錯誤的?

+0

用\ \轉義它。 – rgin

+0

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

+3

這是一個非常糟糕的主意......即使您使用反斜槓轉義單引號,您也會冒SQL注入攻擊的風險。你需要理解字符編碼,但是這種天真的方法有一個嚴重的(已知的)漏洞。在查詢中使用綁定參數並允許DBMS安全地傳輸值。 – d11wtq

回答

61

如果必須這樣,那麼連接對象上使用quote method做到這一點:

報價(值,列=無)
行情的列值,以幫助防止SQL注入攻擊。

因此,像這樣:

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); 

永遠不要試圖處理你自己的報價。並且不要試圖用雙引號引用SQL字符串,這就是單引號的用途;雙引號用於引用大多數數據庫中的標識符(例如表名和列名),但MySQL使用反引號。

+0

由於我使用的變量MY_NAME,我想我可以使用MY_NAME =的ActiveRecord :: Base.connection.quote(NAME_VARIABLE) –

+0

@ Leem.fin:對。或者你可以把它放在字符串插值的內部,但這會讓你的代碼難以閱讀。 –

+0

我認爲在你的代碼中有一個錯誤,你應該刪除查詢VALUES部分中的單引號,因爲quote()方法已經爲該字符串添加了引號。現在,如果我運行代碼就像你說的,我得到的SQL語法錯誤,因爲我有「約翰的公司」爲價值 –