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程序简介(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 车开着开着就熄火了,电瓶灯一闪一闪的是怎
- 下一篇: linux cmake编译源码,linu