导轨4,单质量插入

时间:2016-07-05 09:21:49

标签: ruby-on-rails postgresql ruby-on-rails-4

我正在尝试通过使用单个质量插入而不是多次调用ActiveRecord的create方法来导入数据来优化我的rake任务的性能。

这是我写的代码:

inserts = []
orders.each do |ord|
  inserts.push "('#{ord.company}', '#{ord.number}', '#{ord.line}', '#{Time.now.to_s(:db)}', '#{ord.comment}')"
end
sql = "INSERT INTO orders (company, number, line, created_at, comment) VALUES #{inserts.join(", ")}"
ActiveRecord::Base.connection.execute(sql)

问题是comment字符串可以包含'字符,因此生成的sql查询字符串将如下所示:

  

INSERT INTO订单(公司,编号,行,created_at,评论)VALUES   (' 100',' 023074',' 001',' 2016-07-05 11:17:38','转型K7'),   (' 100',' 023943',' 001',' 2016-07-05 11:17:38',' BANDE PE D' AMARRAGE')

这将生成

  

PG :: SyntaxError:ERROR:语法错误在或附近" AMARRAGE"

我该如何处理?

4 个答案:

答案 0 :(得分:1)

问题是您的字符串引号正在关闭SQL查询中的字符串值。试试escaping them

'#{ord.comment.gsub("'"){ "\\'" }'

这样,SQL查询将包含有效的字符串。

此外,你不应该做你想做的事情。如果comment属性包含sql代码,则可能会注入,并对数据库执行令人讨厌的操作。请阅读this。安全!

答案 1 :(得分:0)

请尝试以下操作。

Order.sanitize(ord.comment)

答案 2 :(得分:0)

Postgresql 中,转义字符为single quote。因此,如果您想使用connection.execute方法大量插入数据库,请将single quote替换为two single quotes

这是代码示例。

inserts = []
orders.each do |ord|
  inserts.push "('#{ord.company}', '#{ord.number}', '#{ord.line}', '#{Time.now.to_s(:db)}', '" + ord.comment.gsub("'","''")   + "')"
end
sql = "INSERT INTO orders (company, number, line, created_at, comment) VALUES #{inserts.join(", ")}"
ActiveRecord::Base.connection.execute(sql)

答案 3 :(得分:0)

我最终使用ActiveRecord::Base.connection.quote方法:

inserts = []
orders.each do |ord|
  company = ActiveRecord::Base.connection.quote(ord.company)
  number = ActiveRecord::Base.connection.quote(ord.number)
  line = ActiveRecord::Base.connection.quote(ord.line)
  comment = ActiveRecord::Base.connection.quote(ord.comment)
  inserts.push "(#{company}, #{number}, #{line}, '#{Time.now.to_s(:db)}', #{comment})"
end
sql = "INSERT INTO orders (company, number, line, created_at, comment) VALUES #{inserts.join(", ")}"
ActiveRecord::Base.connection.execute(sql)