我需要向 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
考虑到我每天有成千上万的元素要插入,我也不能使用这个解决方案。
最佳答案
好吧,有几件事:
-
github.com/go-sql-driver/mysql
似乎定义了实现标准error
接口(interface)的MySQLWarnings
类型,所以我确信它有办法在执行查询或扫描结果行时返回这些警告的查询。我会深入研究资源以找出答案。 - MySQL 本身支持
SHOW WARNINGS
statement这样您就可以在执行INSERT
语句后查询它并遍历返回的行。
关于mysql - 使用 INSERT IGNORE 检索警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24700807/