Golang中MySQL的RowsAffected返回值为零的问题
Golang中MySQL的RowsAffected返回值为零的问题
我们尝试执行删除或更新操作,并试图获取受影响的行数。它返回了零。
5 回复
你能分享一下你的代码吗?另外,你是否检查过是否返回了错误?你是否确认数据确实已从表中删除?
更多关于Golang中MySQL的RowsAffected返回值为零的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的,既然你检查了错误。
你说受影响的行数返回零,我假设在此之前没有错误,那么能否请你回答那个仍然悬而未决的问题:你是否检查过数据库,确认实际上有数据被删除了?
我已经检查过记录是否已存在。
我通过修改以下代码解决了这个问题:
tx, err := easyglobal.Mydb.Begin()
if err != nil {
return false, err
}
defer func(tx *sql.Tx) {
if err != nil {
_ = tx.Rollback()
} else {
_ = tx.Commit()
}
}(tx)
将 beingX 改为 begin,并将 Sqlx 改为 sql。
如果你知道原因,请详细解释给我听。
tx, err := Mydb.Beginx()
if err != nil {
return false, err
}
defer func(tx *sqlx.Tx) {
if err != nil {
_ = tx.Rollback()
} else {
_ = tx.Commit()
}
}(tx)
_Query := `delete from emp where emp_id = ? `
rowsaffected, err := tx.Exec(_Query, _in.Emp_id)
if err != nil {
return false, err
}
nRows, err := rowsaffected.RowsAffected()
if err != nil {
//fmt.Println("Error: Failed to read count of affected rows")
log.Fatal(err)
return false, err
}
if nRows <= 0 {
//return false, err
}
在Golang中,RowsAffected()返回零通常有几个常见原因。以下是具体分析和示例代码:
1. SQL语句未实际影响任何行
// 示例:没有匹配WHERE条件的记录
result, err := db.Exec("UPDATE users SET status = ? WHERE id = ?", "active", 999)
if err != nil {
log.Fatal(err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("受影响行数: %d\n", rowsAffected) // 如果id=999不存在,返回0
2. 使用sqlx时的常见问题
// 错误示例:使用sqlx的NamedExec时获取受影响行数
type User struct {
ID int `db:"id"`
Status string `db:"status"`
}
user := User{ID: 1, Status: "inactive"}
result, err := db.NamedExec("UPDATE users SET status = :status WHERE id = :id", user)
if err != nil {
log.Fatal(err)
}
// 正确获取RowsAffected
rowsAffected, err := result.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("受影响行数: %d\n", rowsAffected)
3. 事务中的问题
// 示例:在事务中检查受影响行数
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
result, err := tx.Exec("DELETE FROM logs WHERE created_at < ?", time.Now().AddDate(0, -1, 0))
if err != nil {
tx.Rollback()
log.Fatal(err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
tx.Rollback()
log.Fatal(err)
}
if rowsAffected == 0 {
fmt.Println("没有符合条件的记录被删除")
} else {
fmt.Printf("删除了 %d 条记录\n", rowsAffected)
}
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
4. 检查SQL执行是否成功
// 完整示例:包含错误处理和调试
func deleteUser(db *sqlx.DB, userID int) (int64, error) {
result, err := db.Exec("DELETE FROM users WHERE id = ?", userID)
if err != nil {
return 0, fmt.Errorf("执行删除失败: %v", err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return 0, fmt.Errorf("获取受影响行数失败: %v", err)
}
// 调试:打印最后执行的SQL(需要开启驱动日志)
fmt.Printf("删除用户ID: %d, 受影响行数: %d\n", userID, rowsAffected)
return rowsAffected, nil
}
5. 确保使用正确的Result对象
// 错误示例:使用了错误的结果对象
stmt, err := db.Prepare("UPDATE products SET price = ? WHERE category = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
// 错误:尝试在stmt上调用RowsAffected
// rowsAffected, err := stmt.RowsAffected() // 编译错误
// 正确:在Exec返回的Result上调用
result, err := stmt.Exec(99.99, "electronics")
if err != nil {
log.Fatal(err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
log.Fatal(err)
}
6. 验证数据库连接和表状态
// 检查数据库连接和表是否存在
func checkDatabase(db *sqlx.DB) error {
// 检查连接
err := db.Ping()
if err != nil {
return fmt.Errorf("数据库连接失败: %v", err)
}
// 检查表是否存在
var tableExists bool
err = db.Get(&tableExists,
"SELECT COUNT(*) > 0 FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'users'")
if err != nil {
return fmt.Errorf("检查表失败: %v", err)
}
if !tableExists {
return fmt.Errorf("表不存在")
}
return nil
}
如果以上方法都不能解决问题,可以在执行SQL前添加调试日志,确保SQL语句正确执行:
// 调试:打印实际执行的SQL
query := "DELETE FROM orders WHERE status = ? AND created_at < ?"
args := []interface{}{"pending", time.Now().AddDate(0, -6, 0)}
fmt.Printf("执行SQL: %s\n参数: %v\n", query, args)
result, err := db.Exec(query, args...)
// ... 后续处理

