【发布时间】:2021-07-19 07:02:22
【问题描述】:
我正在尝试更新数据库中的一条记录,根据rowsAffected() 计数,我可以确定该记录是否存在。在这种情况下,如果没有 (rowsAffected() == 0),我将运行插入查询。
func (u *UserService) NewAddress(l *models.Address) error {
var err error
db, err := database.GetConnection()
if err != nil {
return err
}
defer db.Close()
sql := `UPDATE Locations SET Address = ?, StateId = ? WHERE Id = ?`
query := `INSERT INTO Locations (UserId, StateId, Address, City, StreetName, StreetNumber, Code, Latitude, Longitude) VALUES(?,?,?,?,?,?,?,?,?)`
stmt, err := db.Prepare(sql)
if err != nil {
return err
}
results, err := stmt.Exec("Port St Johns, South Africa", l.StateId, l.Id)
if err != nil {
return err
}
fmt.Println(results.RowsAffected())
if affected, err := results.RowsAffected(); err == nil {
if affected == 0 {
insert, err := db.Query(query, l.UserId, l.StateId, l.Address, l.City, l.StreetName, l.StreetNumber, l.Code, l.Latitude, l.Longitude)
defer insert.Close()
if err != nil {
return err
}
}
}
return nil
}
但是,如果我正在更新的列的值 e.i Address 与已存储在数据库中的值相同,则 RowsAffected() 函数始终返回 0。如果找不到我要更新的记录,它也会返回 0。
如果我直接在 MySQL 控制台上运行相同的查询,即使更新(地址)完全相同,只要满足 WHERE 子句条件,它总是返回 Update Rows >= 1。
UPDATE Locations
SET Address = "Port St Johns", StateId = 2
WHERE Id = 102;
我可以做不同的更新吗?我试图避免 select 查询以在更新/插入之前检查记录是否存在。
【问题讨论】:
-
你试过 ROW_COUNT(); 吗?它不是替代解决方案,但是您可以通过比较结果来发现问题所在。
-
你可以在你的表中有一个时间戳列,比如
updated_at,你每次发出更新查询时都会更新到当前时间戳,这样row_count()mysql 函数将始终返回如果更新匹配一行或多行,则为大于 0 的数字。另请注意,row_count()被定义为仅返回受更改影响的行数,因此您使用的 MySQL 控制台与实际的 mysql 数据库输出不一致。 -
... 例如,尝试使用
mysql命令行工具运行查询,并且在执行不更改单个列的更新时,您将看到类似于以下@987654337 的输出@,当您随后调用select row_count();时,您将返回0。所以你可以看到 MySQL 控制台 UI 在这种情况下说"Updated Rows 1"具有误导性,不正确,不正确,错误!没有更新行。是的,匹配了一行,但没有更新。 -
作为使用
"updated_at"列的替代方法,如果您想“避免在更新/插入之前检查记录是否存在的select查询”,我假设你也可以使用INSERT ... ON DUPLICATE KEY UPDATE。