我需要使用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
答案 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?
中使用预准备语句的几个选项