2016-11-17 62 views
0

我需要使用ruby scipt更新一個數據庫表與另一個數據庫表的數據。如果該字段中有單引號,則會引發該錯誤。如何避免它?使用單引號更新數據庫失敗Ruby on Rails

在下面的示例中,它無法插入nish's。

A_db: products table info: 
    id text 
    ---------------- 
     1 hashh 
     2 nish's 
A_db = Mysql2::Client.new(
      :host => "xxx", 
      :username => "xxx", 
      :database => "xxx", 
      :password => "xxx") 
B_db = Mysql2::Client.new(
      :host => "zzz", 
      :username => "xxx", 
      :database => "xxx", 
      :password => "xxx") 

Adata = A_db.query("select * from products;") 
Adata.each do |d| 
    id= d['id'] 
    B_db.query("insert ignore into products(id, text) values('#{id}', '#{d['text']}')") 
end 
+3

是的,你需要逃避'd [「文本」]'的價值,因爲它可能包含單個引用(或更糟糕的是:執行SQL注入的代碼)。 – Wukerplank

+0

你有沒有考慮用普通的'SQL'來做這件事?似乎根本就不需要Ruby。 SQL將比將所有內容加載到內存中快得多。 – spickermann

+0

@Wukerplank如何在這句話中逃避它? –

回答

0

你或多或少對外開放SQL注入這裏。這不是最佳的,所以你應該以任何方式保護自己。問題是你的字符串被認爲是你的sql語句的一部分。有幾種方法可以避免這種情況。一種方法是使用準備好的語句。

在這個問題上,他們討論了幾個選項,在紅寶石How do I create a prepared insert statement in Sequel?

+0

不多或少。這絕對是一個SQL注入:) –

1

可以使用Mysql2::Client.escape method使用預處理語句。

但是不要。相反,使用準備好的語句。準備好的語句是避免SQL注入攻擊的最佳方式。

的Mysql2自述有準備的語句in its Usage section,我將在這裏重複爲子孫後代的一個例子:

準備語句的支持,以及。在準備好的語句中, 使用?代替每個值,然後執行語句 檢索結果集。將您的參數傳遞給與 中執行方法相同的數量和順序作爲語句中的問號。

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

所以,你的查詢會是這個樣子:

statement = B_db.prepare("INSERT IGNORE INTO products (id, text) VALUES (?, ?)") 
statement.execute(d["id"], d["text"])