踩坑系列之 mysql的effect rows

前言

這周的時候,和老鐵就GoLang中mysql的“effect rows”這個問題討論起來。

關鍵點在於:在進行update操作的時候,如果不進行更新(也可以理解爲當前數據庫就是這樣子了)或者沒這條數據,effect rows都會爲0。

假設一個場景,需要區分這兩種情況,就沒法解決了。

正文

解決方案尋找過程

1. 命令行驗證在這裏插入圖片描述

通過命令行操作數據庫,可以看到,mysql客戶端是區分了matched的行數和changed的行數,是可以區分出來上文的情況的。

2. go-mysql包源碼

終於找到方式了,那麼go的mysql包是不是可以?
後面發現golang的mysql包結果的定義是這樣:

type Result interface {
   LastInsertId() (int64, error)
   RowsAffected() (int64, error)
}

在這裏插入圖片描述
竟然沒有!!想象中的,Rows matched!!

3. 網上搜索

那隻好在網上尋找解決方案:
在這裏插入圖片描述
這個老外說不可能,what·s your problem?

後面發現CLIENT_FOUND_ROWS蘊含着巨大的能量。

對於update且是CLIENT_FOUND_ROWS時affected_rows返回的是found的行數
對於update且不是CLIENT_FOUND_ROWS是返回的是實際更新的行數

4.實戰驗證

package main
 
import (
   "database/sql"
   "fmt"
   _ "github.com/go-sql-driver/mysql"
)
 
func main() {
   // 這裏是默認情況:db, err := sql.Open("mysql", "root:@/test")
   // 這裏是能區分的情況
   db, err := sql.Open("mysql", "root:@/test?clientFoundRows=true")
   if err != nil {
      panic(1)
   }
    
   stmt, err := db.Prepare("update test set name=? where id=?")
   if err != nil {
      panic(1)
   }
 
   res, err := stmt.Exec("34", 1)
   effectRow, _ := res.RowsAffected()
   fmt.Println(effectRow)
}

以上代碼單純考慮解決的角度看的,實際情況還需要考慮:

1.如果有使用mysql中間價的話,是不是開放了這個配置clientFoundRows?(因爲據我瞭解這個不是單純的開一個配置,對於中間價連接池的改造是有一定工作的)
2.開了這個配置之後,對於項目中現存的所有sql語句是否會產生未知的影響?

結論

記住clientFoundRows參數可以區分。

如果你覺得有收穫~可以關注我的公衆號【咖啡色的羊駝】~第一時間收到我的分享和知識梳理~
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章