我需要在 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...)
Run Code Online (Sandbox Code Playgroud)
如果我在终端中运行此查询,我会将被拒绝的行作为警告:
Warning | 1062 | Duplicate entry '4' for key 'uk-uniquekey'
Run Code Online (Sandbox Code Playgroud)
但是我怎么能用 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)
}
Run Code Online (Sandbox Code Playgroud)
与扩展插入查询相比,我对这个解决方案进行了基准测试。对于 1000 个条目(我承认我的机器不是很有竞争力......),这是我的结果:
Loop on prepared single insert: 10.652721825 s
Single extended insert: 0.092304425 s
Run Code Online (Sandbox Code Playgroud)
考虑到我每天要插入数千个元素,我也无法使用此解决方案。
嗯,有几件事:
github.com/go-sql-driver/mysql似乎定义了MySQLWarnings实现标准error接口的类型,所以我确信它有办法在执行查询或扫描查询结果的行时返回这些警告。我会深入研究来源以找出答案。SHOW WARNINGS语句,因此您可以在执行INSERT语句后查询它并迭代返回的行。| 归档时间: |
|
| 查看次数: |
1438 次 |
| 最近记录: |