mysql多次調(diào)用存儲過程的問題
更新時間:2011年05月07日 23:59:15 作者:
這個問題也困擾了我很長時間,準確的說正是因為他的存儲過程無法在同一連接中2次或者多次執(zhí)行,我大幅修該了程序架構(gòu),全部題換成了sql,但是畢竟sql無法執(zhí)行有相當(dāng)邏輯的代碼,最總讓我從新測試以求尋找解決之道。
問題是這樣的,在直接使用mysql c api構(gòu)建應(yīng)用的時候,一個連接只能執(zhí)行一次存儲過程,不管怎樣free再次利用這個連接的時候就會出現(xiàn)不能執(zhí)行qurry的提示,我想,這么大型的軟件 不會存在這樣的基礎(chǔ)性問題吧,畢竟大多數(shù)的adodb都是基于c api的,難道所有的軟件都無法進行連接緩存?
別說,接觸到這類問題的人還真不多,大多數(shù)的連接池都寫好了,誰會去直接構(gòu)建連接進行操作呢,所以baidu google基本都沒有結(jié)果,今天回頭來解決這個問題,突然就有了突破,找到了一篇文章《對Mysql的C API調(diào)用存儲過程的問題及解決方法分析》,正是我的問題。
作者分析的挺復(fù)雜了,其實我們一般只用mysql_query、mysql_use_result等幾個函數(shù),問題的癥結(jié)在于當(dāng)執(zhí)行一個存儲過程的時候, 數(shù)據(jù)庫返回的是多個數(shù)據(jù)集合,即使只有一個數(shù)據(jù)集合,他也會有一個空集合用于結(jié)束一次回話,作者罵他變態(tài),其實不然,可能作者考慮到的只是一般的請 求,mysql是給所有用戶使用的,說不能真有變態(tài)的人把圖片文件等等直接保存在mysql字段里面,那么回復(fù)就不可能一次完成,需要多此網(wǎng)絡(luò)交互,那么 所有的交互肯定需要一個結(jié)束符號,并且存儲過程本來就可以返回多個數(shù)據(jù)集合,如果他在c pai中只做一個結(jié)果己處理就允許下一次全新的請求,那么對于同一連接,在mysql服務(wù)斷其實還有沒有發(fā)送完成的數(shù)據(jù),這個時候他安全的做法就是不接受 任何新的請求,直到數(shù)據(jù)發(fā)送完全,或者連接關(guān)閉,不然,mysql協(xié)議解析就會出現(xiàn)問題,下次發(fā)送就會出現(xiàn)黏包或者丟包,所以他的做法是完全正確的,即使 只有一個結(jié)果集合,也需要當(dāng)前會話內(nèi)的通訊(比如mysql_next_result)確認完畢,然后結(jié)束本次請求,這個時候服務(wù)端其實沒有數(shù)據(jù)了,但是 這個過程是不能省略的,然后在不關(guān)閉連接的情況下就可以進行全新的請求了。
所以總結(jié)起來就是:使用存儲過程的時候一定要循環(huán)執(zhí)行,把所有的結(jié)果集合都取到,直到為空,這個時候當(dāng)前數(shù)據(jù)庫連接才可以安全歸還回去,下面是demo。
MYSQL_RES *conn;
MYSQL_RES *res;
MYSQL_ROW row;
conn = 連接池.Get("xxxx");
mysql_query(conn, "call qt()");
res = mysql_use_result(conn);
while ((row = mysql_fetch_row(res))) {
do main thins; //這次是對于第一個數(shù)據(jù)集的處理
}
mysql_free_result(res);
while ((res = mysql_next_result(conn)) != NULL) {
do some thing; //循環(huán)處理其他的數(shù)據(jù)集
mysql_free_result(res);
}
連接池.Free(conn)
經(jīng)過上面的循環(huán)讀取就能夠保證一條連接會干凈地歸還到連接池,當(dāng)然有的連接池可能已經(jīng)把后面一個循環(huán)放在連接池中處理了,解釋說把剩余的數(shù)據(jù)集全部取過來然后釋放,這樣比如在php等里面使用mysql的連接池的時候就沒有感受到上面說的問題。
別說,接觸到這類問題的人還真不多,大多數(shù)的連接池都寫好了,誰會去直接構(gòu)建連接進行操作呢,所以baidu google基本都沒有結(jié)果,今天回頭來解決這個問題,突然就有了突破,找到了一篇文章《對Mysql的C API調(diào)用存儲過程的問題及解決方法分析》,正是我的問題。
作者分析的挺復(fù)雜了,其實我們一般只用mysql_query、mysql_use_result等幾個函數(shù),問題的癥結(jié)在于當(dāng)執(zhí)行一個存儲過程的時候, 數(shù)據(jù)庫返回的是多個數(shù)據(jù)集合,即使只有一個數(shù)據(jù)集合,他也會有一個空集合用于結(jié)束一次回話,作者罵他變態(tài),其實不然,可能作者考慮到的只是一般的請 求,mysql是給所有用戶使用的,說不能真有變態(tài)的人把圖片文件等等直接保存在mysql字段里面,那么回復(fù)就不可能一次完成,需要多此網(wǎng)絡(luò)交互,那么 所有的交互肯定需要一個結(jié)束符號,并且存儲過程本來就可以返回多個數(shù)據(jù)集合,如果他在c pai中只做一個結(jié)果己處理就允許下一次全新的請求,那么對于同一連接,在mysql服務(wù)斷其實還有沒有發(fā)送完成的數(shù)據(jù),這個時候他安全的做法就是不接受 任何新的請求,直到數(shù)據(jù)發(fā)送完全,或者連接關(guān)閉,不然,mysql協(xié)議解析就會出現(xiàn)問題,下次發(fā)送就會出現(xiàn)黏包或者丟包,所以他的做法是完全正確的,即使 只有一個結(jié)果集合,也需要當(dāng)前會話內(nèi)的通訊(比如mysql_next_result)確認完畢,然后結(jié)束本次請求,這個時候服務(wù)端其實沒有數(shù)據(jù)了,但是 這個過程是不能省略的,然后在不關(guān)閉連接的情況下就可以進行全新的請求了。
所以總結(jié)起來就是:使用存儲過程的時候一定要循環(huán)執(zhí)行,把所有的結(jié)果集合都取到,直到為空,這個時候當(dāng)前數(shù)據(jù)庫連接才可以安全歸還回去,下面是demo。
復(fù)制代碼 代碼如下:
MYSQL_RES *conn;
MYSQL_RES *res;
MYSQL_ROW row;
conn = 連接池.Get("xxxx");
mysql_query(conn, "call qt()");
res = mysql_use_result(conn);
while ((row = mysql_fetch_row(res))) {
do main thins; //這次是對于第一個數(shù)據(jù)集的處理
}
mysql_free_result(res);
while ((res = mysql_next_result(conn)) != NULL) {
do some thing; //循環(huán)處理其他的數(shù)據(jù)集
mysql_free_result(res);
}
連接池.Free(conn)
經(jīng)過上面的循環(huán)讀取就能夠保證一條連接會干凈地歸還到連接池,當(dāng)然有的連接池可能已經(jīng)把后面一個循環(huán)放在連接池中處理了,解釋說把剩余的數(shù)據(jù)集全部取過來然后釋放,這樣比如在php等里面使用mysql的連接池的時候就沒有感受到上面說的問題。
您可能感興趣的文章:
- mysql 存儲過程中變量的定義與賦值操作
- mysql存儲過程 游標 循環(huán)使用介紹
- MySQL存儲過程例子(包含事務(wù),輸出參數(shù),嵌套調(diào)用)
- MySQL存儲過程使用實例詳解
- MySQL 有輸入輸出參數(shù)的存儲過程實例
- mysql存儲過程 在動態(tài)SQL內(nèi)獲取返回值的方法詳解
- MySQL 存儲過程中執(zhí)行動態(tài)SQL語句的方法
- mysql存儲過程中使用游標的實例
- 深入mysql創(chuàng)建自定義函數(shù)與存儲過程的詳解
- MySQL 存儲過程的基本用法介紹
- MySQL實現(xiàn)創(chuàng)建存儲過程并循環(huán)添加記錄的方法
相關(guān)文章
MAC上Mysql忘記Root密碼或權(quán)限錯誤的快速解決方案
這篇文章主要介紹了MAC上Mysql忘記Root密碼或權(quán)限錯誤的快速解決方案的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-06-06Python MySQL進行數(shù)據(jù)庫表變更和查詢
這篇文章主要介紹了Python MySQL進行數(shù)據(jù)庫表變更和查詢的相關(guān)資料,需要的朋友可以參考下2017-05-05SQL Server 2005 安裝遇到的錯誤提示和解決方法
在安裝SQL Server 2005時有時會出現(xiàn)意想不到的問題,如IIS,性能計數(shù)器,OWC11,無法配置外圍應(yīng)用的問題,下面筆者分享一下在安裝SQL Server 2005時常見問題解決方法2014-01-01MySQL 如何設(shè)計統(tǒng)計數(shù)據(jù)表
有些時候,改進數(shù)據(jù)表查詢性能的最佳方式是在同一張數(shù)據(jù)表中冗余一些繼承的數(shù)據(jù)。然而,有些時候需要新建完全獨立的統(tǒng)計或緩存數(shù)據(jù)表,尤其是在需要反復(fù)查詢的需求情況下。如果業(yè)務(wù)允許一些時間上的誤差的話,那么這種方式會更好。2021-06-06MySQL數(shù)據(jù)庫設(shè)計之利用Python操作Schema方法詳解
這篇文章主要介紹了MySQL數(shù)據(jù)庫設(shè)計之利用Python操作Schema方法詳解,還是比較不錯的,這里分享給大家,供需要的朋友參考。2017-11-11