日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

c 窗体程序 mysql_C\C++开发MySQL程序简介(下)

發布時間:2024/9/19 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c 窗体程序 mysql_C\C++开发MySQL程序简介(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如果需要向數據庫中存儲BLOB數據,則不能單純的使用字符串,因為BLOB數據中很可能含有0。

一般有兩種方法用來存儲BLOB數據,一個是通過MYSQL提供的轉義函數:

unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)

該函數將“from”中的字符串編碼為轉義SQL字符串。將結果置于“to”中,并添加1個終結用NULL字節。編碼的

字符為NUL (ASCII 0)、‘\n’、‘\r’、‘\’、‘'’、‘"’等。

注意,必須為“to”緩沖區分配至少length*2+1字節,以保證在最壞情況下不會溢出。

另一種方法則是通過MYSQL預處理函數進行BLOB數據的存儲。

下面先介紹預處理函數。

MySQL客戶端/服務器協議提供了預處理語句。該功能采用了由mysql_stmt_init()初始化函數返回的MYSQL_STMT語句處理程序數據結構。對于多次執行的語句,預處理執行是一種有效的方式。首先對語句進行解析,為執行作好準備。接下來,在以后使用初始化函數返回的語句句柄執行一次或多次。

對于多次執行的語句,預處理執行比直接執行快,主要原因在于,僅對查詢執行一次解析操作。在直接執行的情況下,每次執行語句時,均將進行查詢。此外,由于每次執行預處理語句時僅需發送參數的數據,從而減少了網絡通信量。

預處理語句的另一個優點是,它采用了二進制協議,從而使得客戶端和服務器之間的數據傳輸更有效率。

下述語句可用作預處理語句:CREATE TABLE、DELETE、DO、INSERT、REPLACE、SELECT、SET、UPDATE、以及大多數SHOW語句。在MySQL 5.1中,不支持其他語句。

預處理函數有兩個核心的數據類型,MYSQL_STMT和MYSQL_BIND,關于MYSQL_STMT完全不需要理解,關于MYSQL_BIND需要查看下手冊,接下來的一些函數需要用到它。

/*初始化,使用預處理語句必須先調用該函數*/

MYSQL_STMT *mysql_stmt_init(MYSQL *mysql);

/*準備語句*/

int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length);

/*綁定參數*/

my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind);

/*綁定結果*/

my_bool mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind);

/*執行SQL語句*/

int mysql_stmt_execute(MYSQL_STMT *stmt);

/*使用完后需要釋放資源*/

my_bool mysql_stmt_close(MYSQL_STMT *);

對于預處理流程,MYSQL提供了很多和普通流程同樣的接口,比如獲取記錄集,獲取一行記錄,獲取SQL語句影響的行數,以及錯誤處理函數等,只是在函數名中加入了stmt,查下手冊就可以了。

這里稍微解釋下mysql_stmt_prepare函數和mysql_stmt_bind_param函數,一般來說,需要使用到預處理流程的,都是SQL語句格式固定,只是有一兩個值在變化,比如:

INSERT INTO mytbl VALUES(?,?,?)

這里的三個問號就是三個參數,如果你寫過存儲過程應該很好理解。

通過將問號字符“?”嵌入到SQL字符串的恰當位置,應用程序可包含SQL語句中的一個或多個參數標記符。

標記符僅在SQL語句中的特定位置時才是合法的。例如,它可以在INSERT語句的VALUES()列表中(為行指定列值),或

與WHERE子句中某列的比較部分(用以指定比較值)。但是,對于ID(例如表名或列名),不允許使用它們,不允許指定二進

制操作符(如等于號“=”)的操作數。后一個限制是有必要的,原因在于,無法確定參數類型。一般而言,參數僅在DML(數據

操作語言)語句中才是合法的,在DDL(數據定義語言)語句中不合法。

將這條語句prepare好后,就可以進行綁定參數了,當然在調用函數前,需要先將MYSQL_BIND結構體準備好,比如上邊這條語句有3個參數,那么就需要準備一個數組

MYSQL_BIND bind[3]={0};

......

mysql_stmt_bind_param(stmt,bind);

再回到開頭的問題,如果需要存儲BLOB數據,那么我們可以設置MYSQL_BIND結構體綁定到一個buffer,然后執行SQL語句即可

MYSQL * mysql = NULL;

......

MSYQL_STMT * stmt = mysql_stmt_init(mysql);

const char * strSql = "insert into mytable(id,content) values(1,?)";

mysql_stmt_prepare(stmt,strSql,strlen(strSql));

char buffer[128]={0};

int len = 128;//數據的長度

/*通過memcpy等向buffer中復制數據*/

MYSQL_BIND bind;

bind.buffer_type = MYSQL_TYPE_BLOB;

bind.buffer = buffer;

bind.buffer_length = &len; //這個長度是指緩沖區的最大長度

bind.is_null = 0;

bind.length = &len;//這個指數據的實際長度

mysql_stmt_bind_param(stmt,&bind);

mysql_stmt_execute(stmt);

...

mysql_stmt_close(stmt);

不管使用普通流程還是預處理流程,在讀取BLOB數據時,你需要用到下邊的函數來獲取數據的長度:

/*該函數返回一個指針,你可以通過索引值來獲得相應的列的值的長度*/

/*每次獲取一行新記錄,你都需要調用該函數*/

unsigned long *mysql_fetch_lengths(MYSQL_RES *result); 下一篇將會給出一些比較完整的例子

總結

以上是生活随笔為你收集整理的c 窗体程序 mysql_C\C++开发MySQL程序简介(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。