iT邦幫忙

0

Go語言如何計算MySQL資料庫回傳資料筆數?

小弟最近在學習 golang
在練習使用 go-sql-driver/mysql 讀取 MySQL 資料庫時
遇到一個問題:
如何知道執行一個SQL指令之後的筆數?
例如:用SELECT查詢所返回的總筆數。

在 Python 使用 pymysql 時
只要用到 execute(SQL指令)
(不論是 SELECT、UPDATE、或DELETE)就可以立即得到回應筆數。

在PHP也可以使用mysql_num_rows()函數查詢總筆數。

請問各位前輩 go-sql-driver/mysql 有類似的機制嗎?
或有其他的 Mysql driver 可達到此目的?

kjfang iT邦新手 5 級 ‧ 2019-11-12 09:36:31 檢舉
昨天試了一天
後來查到下面這個簡體字網頁(看網址不像是大陸的網頁)
[深入剖析在事务中并发执行查询异常]
(https://medium.com/impopper-engineering/go-concurrency-query-in-mysql-transactions-f6018c7b16b2)
發現同一個Section中,若不清空SELECT資料
無法再執行一次查詢。
目前看來,剩下兩條路可走

一是froce大之前建議的方法
讓資料庫在不同的Section跑兩次查詢
一次是SELECT要抓取的資料
另一次是用同樣條件的SELECT COUNT(*)

另一個方法是
在golang裡面開一個空間(slice)
把SELECT出來的資料全部裝進去
再計算slice的長度

兩個方法似乎都不是很理想
一個浪費資料庫的查詢時間
另一個耗費golang的buffer空間及處理時間

請問各位
有更好的方法嗎?

2 個回答

0
dragonH
iT邦超人 5 級 ‧ 2019-11-11 11:42:30

mysql_num_rows() 我記得也只能用在 select

對 golang 不熟

不過

或許你可以試試

RowsAffected()

參考1

參考2

未實測過

kjfang iT邦新手 5 級 ‧ 2019-11-11 12:32:54 檢舉

RowsAffected() 在 MySQL 5.5 版以後被停用了
所以,用在 SELECT 裡面,跑出如下的錯誤訊息:
[Err] 1305 - FUNCTION RowsAffected does not exist

至於您提供的 參考1 看起來似乎是個方向
只是,我是 golang 的初學者
目前試了幾次,都回錯誤
看來,還要多瞭解 golang 的用法。

dragonH iT邦超人 5 級 ‧ 2019-11-11 13:45:51 檢舉

不是要用在 select裡啦XD

參考二目的是要給你看他怎麼 call RowsAffected()

kjfang iT邦新手 5 級 ‧ 2019-11-12 09:47:01 檢舉

網路上看了一些例子
RowsAffected()應該是用在UPDATE、DELETE、INSERT上面
SELECT似乎沒辦法這樣用
或許修改您提供的 參考1 可取得SELECT筆數
可惜小弟目前沒有這個能力

0
froce
iT邦大師 1 級 ‧ 2019-11-11 11:44:08
var count int
rows := db.QueryRow("select count()  ....")
rows.Scan(&count)
return count

PS我沒實際用過,沒在用mysql

建議去用ORM,直接用driver好像都會有這種問題,driver不一定有做這些api。

或者像這樣在sql中直接寫count(*)

看更多先前的回應...收起先前的回應...
kjfang iT邦新手 5 級 ‧ 2019-11-11 12:41:38 檢舉

froce大
試了幾次,似乎無法直接這樣用。
好像要另外寫一個 SELECT COUNT() 來抓。
但是,COUNT()不能直接放在一個多Table的SELECT查詢裡面
意思是,要連做兩次同樣條件的查詢嗎?

froce iT邦大師 1 級 ‧ 2019-11-11 12:56:21 檢舉

這個的用法就是叫你直接select count啊。
go-sql-driver/mysql 剛剛幫你瞄了一下原始碼,沒看到做出Count/Length之類的函式,所以沒辦法直接得到。
這也不是一個driver必要提供的函式就是了。

有這種應用方面的需求建議用ORM,例如GORM。

froce iT邦大師 1 級 ‧ 2019-11-11 13:24:22 檢舉

喔,你要的是update或select的結果?
那D大的參考1就派上用場了

result,err := DB.Exec("....")
rowsaffected,err := result.RowsAffected()
kjfang iT邦新手 5 級 ‧ 2019-11-12 09:07:56 檢舉

小弟主要目的在做成進度條
以告知使用者目前處理的百分比。
所以,
想要知道一開始SELECT出來的總筆數有多少
後續再依據所抓出來的資料逐筆處理
這樣就可以輕鬆的做出進度條了。
因為是逐筆處理
後續INSERT、UPDATE、或DELETE的筆數反倒不重要了

我要發表回答

立即登入回答