【问题标题】:Rails MySQL cannot single mass insertRails MySQL 无法单次批量插入
【发布时间】:2015-11-14 13:48:52
【问题描述】:

这是我在控制器中的创建方法:

def create
    @promo = current_user.promos.build(promo_params)

    if @promo.save
      inserts = []
      params[:user_limit].to_i.times do
        inserts.push "(#{@promo.id}, #{SecureRandom.hex(3).upcase})"
      end
      sql = "INSERT INTO vouchers ('promo_id', 'promo_code') VALUES #{inserts.join(", ")}"
      ActiveRecord::Base.connection.execute(sql)

      redirect_to provider_promo_path(@promo), notice: 'Promo was successfully created.'
    else
      render :new
    end
  end

我的凭证表架构:

class Voucher < ActiveRecord::Base {
            :id => :integer,
      :promo_id => :integer,
    :promo_code => :string,
         :email => :string,
        :status => :integer,
       :user_id => :integer,
    :created_at => :datetime,
    :updated_at => :datetime
}

在上面的控制器方法中,我只想填写promo_idpromo_code 字段。它会导致错误吗?以下是错误信息返回:

Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''promo_id', 'promo_code') VALUES' at line 1: INSERT INTO vouchers ('promo_id', 'promo_code') VALUES

指向这一行:

ActiveRecord::Base.connection.execute(sql)

有什么建议吗?谢谢

更新

我已经编辑了我的代码:

inserts.push "(#{@promo.id}, '#{SecureRandom.hex(3).upcase}')"

但我还有另一个错误是:

ActiveRecord::StatementInvalid in Provider::PromosController#create
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''promo_id', 'promo_code') VALUES (20, 'C23E37'), (20, '2A70D0'), (20, '6557DC')' at line 1: INSERT INTO vouchers ('promo_id', 'promo_code') VALUES (20, 'C23E37'), (20, '2A70D0'), (20, '6557DC')

sql 变量值为:

"INSERT INTO vouchers ('promo_id', 'promo_code') VALUES (21, '0D8D52'), (21, '1F6E58'), (21, 'C049DC')"

为什么还是报错?

【问题讨论】:

  • 查看形成的sql查询,查询中有语法错误
  • 请查看我更新的问题
  • SQL 注入:永远不要将用户给定的参数直接写入 Sting。
  • @Meier,你是对的,但在这种情况下 SQL 注入是不可能的。 @promo.id 始终是整数,SecureRandom.hex(3).upcase 不是用户输入。

标签: mysql ruby-on-rails activerecord


【解决方案1】:

您可以尝试另一种方式。

为所有记录构建一个哈希数组:

inserts = []
params[:user_limit].to_i.times do
  record = {}
  record['promo_id'] = @promo.id
  record['promo_code'] = "#{SecureRandom.hex(3).upcase}"
  inserts << record
end

然后,创建凭证:

Voucher.create(inserts)

【讨论】:

    【解决方案2】:

    这个:

    inserts.push "(#{@promo.id}, #{SecureRandom.hex(3).upcase})"
    

    应该是:

    inserts.push "(#{@promo.id}, '#{SecureRandom.hex(3).upcase}')"
    

    SecureRandom.hex(3).upcase 是一个字符串,所以它应该在您的查询中用引号引起来。

    另外,这是错误的:

    INSERT INTO vouchers ('promo_id', 'promo_code')
    

    应该是:

    INSERT INTO vouchers (`promo_id`, `promo_code`)
    

    您不能在 MySQL 中的列名周围使用引号。

    【讨论】:

    • 嗨,谢谢,我忘了那个。请查看我更新的问题
    • @KrisMP 您应该在此部分删除引号或用反引号 (`) 替换它们:INSERT INTO vouchers ('promo_id', 'promo_code')。您不能在 MySQL 中的列名周围使用引号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多