我需要在MySQL表中插入很多值。其中一些可能会导致错误,但我仍然希望插入有效的错误。因此,我使用INSERT IGNORE
查询。
query := "INSERT IGNORE INTO mytable "
query += "(uniquekey, someotherfield) "
query += "VALUES "
var params []interface{}
for _, element := range elements {
query += "(?, ?),"
params = append(params, element.UniqueKey, element.SomeOtherField)
}
_, err := db.Exec(query[:len(query)-1] + ";", params...)
如果我在终端中运行此查询,我会将被拒绝的行作为警告:
Warning | 1062 | Duplicate entry '4' for key 'uk-uniquekey'
但是如何使用Go?
检索它们使用返回的Result
对象,我可以获得受影响的行数(从而找到被拒绝的行数),但我需要一种方法来清楚地识别这些行。
另外,我要插入很多行,并且我不想对每个行使用INSERT
查询。
这个问题有什么好的解决方案吗?
我想过使用这样一个准备好的查询:
stmt, _ := db.Prepare("INSERT INTO mytable (uniquekey, someotherfield) VALUES (?, ?);")
defer stmt.Close()
for _, element := range elements {
stmt.Exec(element.UniqueKey, element.SomeOtherField)
}
与扩展插入查询相比,我对此解决方案进行了基准测试。对于1000个条目(我承认我的机器不是很有竞争力......),这是我的结果:
Loop on prepared single insert: 10.652721825 s
Single extended insert: 0.092304425 s
考虑到每天要插入数千个元素,我也无法使用此解决方案。
答案 0 :(得分:2)
嗯,有几件事:
github.com/go-sql-driver/mysql
似乎定义了实现标准MySQLWarnings
界面的error
类型,因此我确信它可以在执行查询或扫描时返回这些警告查询结果的行。我会深入了解消息来源。SHOW WARNINGS
statement,因此您可以在执行INSERT
语句后查询它并迭代返回的行。