如果需要向資料庫中儲存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]=;
......
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]=;
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);
Linux系統下C C 開發mysql資料庫應用
一 linux下掛載光碟機 掛載光碟機 mount t iso9660 dev cdrom mnt cdrom 解除安裝光碟機 umount dev cdrom 彈出光碟機 eject 推進光碟機 eject t 二 執行mysql只需安裝 mysql server 3.23.54a 11.i386...
Linux下C C 程式編譯
在編譯之前我們需要在系統裡安裝g gcc,它們就是linux下的c c的編譯器。如下 sudo apt get install build essential sudo apt get install gcc sudo apt get install g 好,現在我們在文字編輯器裡寫乙個c的簡單的程...
linux下編譯C C 程式
c c 的速度是python和perl所無法比擬的,尤其對於處理超大的生物資訊學檔案來說。最近在寫乙個最簡單的fastq cut工具,python簡直慢到不能忍,8g的fastq.gz檔案的cut需要6 7個小時,而c 則只需要15 20min,簡直就不在乙個量級。當然,聽說python有個cpyt...