这是我正在使用的代码
# update db
client = Mysql2::Client.new(:host => "localhost", :username => "jo151", :password => "password", :database => "jo151")
details.each do |d|
if d[:sku] != ""
price = d[:price].split
if price[1] == "D"
currency = 144
else
currency = 168
end
cost = price[0].gsub(",", "").to_f
if d[:qty] == ""
qty = d[:qty2]
else
qty = d[:qty]
end
results = client.query("SELECT * FROM jos_virtuemart_products WHERE product_sku = '#{d[:sku]}' LIMIT 1;")
if results.count == 1
product = results.first
client.query("UPDATE jos_virtuemart_products SET product_sku = '#{d[:sku]}', product_name = '#{d[:desc]}', product_desc = '#{d[:desc]}', product_in_stock = '#{qty}' WHERE virtuemart_product_id =
#{product['virtuemart_product_id']};")
client.query("UPDATE jos_virtuemart_product_prices SET product_price = '#{cost}', product_currency = '#{currency}' WHERE virtuemart_product_id = '#{product['virtuemart_product_id']}';")
else
client.query("INSERT INTO jos_virtuemart_products( product_sku, product_name, product_s_desc, product_in_stock) VALUES('#{d[:sku]}','#{d[:desc]}','#{d[:desc]}','#{d[:qty]}');")
last_id = client.last_id
client.query("INSERT INTO jos_virtuemart_product_prices(virtuemart_product_id, product_price, product_currency) VALUES('#{last_id}', '#{cost}', #{currency});")
end
end
end
`query':第35行的密钥3(Mysql2 :: Error)重复条目''
client.query("INSERT INTO jos_virtuemart_products( product_sku, product_name, product_s_desc, product_in_stock) VALUES('#{d[:sku]}','#{d[:desc]}','#{d[:desc]}','#{d[:qty]}');")
last_id = client.last_id
答案 0 :(得分:1)
使用内联的任意字符串放入原始SQL语句极其危险。你绝对必须逃避任何放入它们的值,以便你的应用程序可以工作。使用撇号获得的第一个描述将导致SQL失败。
在这种情况下,您将在每个字符串上使用client.quote
。没有例外。你可能已经看到很多关于索尼被黑客攻击的新闻,而且正是因为这样的错误导致了严重的违规行为。
你应该调查使用ORM来帮助解决这个问题,即使是像Sequel或DataMapper这样简单的事情,因为它们提供了简化设备的工具。
获取重复键的原因是因为您在其中一个列上插入了一个唯一索引,或者未指定其中一个列,并且该列具有与现有行冲突的默认值。 / p>