单引号更新数据库失败Ruby on Rails

时间:2016-11-17 13:14:07

标签: mysql ruby

我需要使用ruby scipt用另一个数据库更新一个数据库表。如果字段中有单引号,则会抛出错误。怎么避免呢?

在以下示例中,它无法插入nish&#39。

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

2 个答案:

答案 0 :(得分:1)

您可以使用Mysql2::Client.escape method

但不要。相反,使用准备好的陈述。准备好的语句是逃避价值观并保护自己免受SQL注入攻击的最佳方式。

Mysql2 README有一个准备好的语句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"])

答案 1 :(得分:0)

您或多或少在这里开放SQL注入。这不是最佳的,所以你应该以任何方式保护自己。问题是你的字符串被认为是你的sql语句的一部分。有几种方法可以避免这种情况。一种方法是使用准备好的陈述。

在这个问题中,他们讨论了在ruby How do I create a prepared insert statement in Sequel?

中使用预准备语句的几个选项