-- 引子--
由于调试需要,需直接往数据库里写入二进制数据。本来这些数据是由上层软件来写的,用的是 C# 。为了熟悉 C 语言的数据库操作,还是决定用 C 来写这段调试代码。
概况:
表名: Task
涉及的字段及属性:
NumDest : int(11) 用于存储目标数目
destIDs: blob 用于存储具体的目标 ID
废话不多说,入正题。
--二进制数据写入--
二进制数据最为常见的就是图片等一些文件信息。虽然我这里不是这类型信息,但确实是二进制数据。
具体步骤:
1、 定义一个 buffer (如数组)来存储 sql 语句
2、 把涉及到二进制数据之前的 sql 语句添加到 buffer 中,可用 sprintf 或 strcpy 等。
3、 用 mysql_real_escape_string() 函数添加二进制数据到 buffer 中。
4、 加上剩余的 sql 语句,形成完整的 sql 语句。
5、 利用 mysql_real_query() 函数来执行 sql 语句。
具体代码如下:
# include < stdio. h> # include < stdlib. h> # include < mysql/ mysql. h> # include < stdint. h> # include < string . h> int main( int argc, char * argv[ ] ) { MYSQL mysql; char sql[ 256] , * end; int index, i; uint32_t * destIDs; if ( argc ! = 2) { printf ( "enter error!\n" ) ; exit ( 1) ; } index = atoi ( argv[ 1] ) ; printf ( "index: %d\n" , index) ; destIDs = ( uint32_t * ) malloc ( index * sizeof ( uint32_t ) ) ; if ( destIDs = = NULL ) printf ( "malloc error\n" ) ; for ( i= 0; i< index; i+ + ) destIDs[ i] = i + 1; mysql_init( & mysql) ; if ( ! ( mysql_real_connect( & mysql, "localhost" , "root" , "654321" , "dbname" , 0, NULL , 0) ) ) { fprintf ( stderr , "Couldn't connect to engine!\n%s\n" , mysql_error( & mysql) ) ; perror ( "" ) ; exit ( 1) ; } sprintf ( sql, "INSERT INTO Task(NumDest, DestIDs) VALUE (%u, " , index ) ; end = sql + strlen ( sql) ; * end+ + = '\'' ; end + = mysql_real_escape_string( & mysql, end, ( char * ) destIDs, index* sizeof ( uint32_t ) ) ; * end+ + = '\'' ; * end+ + = ')' ; printf ( "end - sql: %d\n" , ( unsigned int ) ( end - sql) ) ; if ( mysql_real_query( & mysql, sql, ( unsigned int ) ( end - sql) ) ) { fprintf ( stderr , "Query failed (%s)\n" , mysql_error( & mysql) ) ; exit ( 1) ; } mysql_close( & mysql) ; exit ( 0) ; # endif return 0; }
--读取二进制文件--
对于二进制文件的读取,也类似。
具体步骤:
1, 构造查询字串 .
2, 执行 mysql _query 查询 . (网上有说用 mysql_real_query ,未实验)
3, 用 mysql_store_result 存储结果 .
4, 用 mysql_fetch_row 取出一条记录处理 .
具体代码如下:
# include < stdio. h> # include < stdlib. h> # include < stdint. h> # include < mysql/ mysql. h> # include < string . h> int main( void ) { int ret, i; char sql[ 256] ; MYSQL mysql; MYSQL_RES * result; MYSQL_ROW row; uint32_t * destIDs, * temp; unsigned int destNum = 0; mysql_init( & mysql) ; if ( ! ( mysql_real_connect( & mysql, "localhost" , "root" , "654321" , "dbname" , 0, NULL , 0) ) ) { fprintf ( stderr , "Couldn't connect to engine!\n%s\n" , mysql_error( & mysql) ) ; perror ( "" ) ; exit ( 1) ; } sprintf ( sql, "SELECT TaskID, NumDest, DestIDs FROM Task" ) ; ret = mysql_query( & mysql, sql) ; if ( ret ! = 0) { printf ( "Failed to query task table: %s\n" , mysql_error( & mysql) ) ; return ret; } result = mysql_store_result( & mysql) ; if ( result = = NULL ) { ret = mysql_errno( & mysql) ; printf ( "Failed to store query result from task table:%s\n" , mysql_error( & mysql) ) ; return ret; } if ( ( row = mysql_fetch_row( result) ) ! = NULL ) { sscanf ( row[ 1] , "%u" , & destNum) ; destIDs = ( uint32_t * ) malloc ( destNum * sizeof ( uint32_t ) ) ; if ( destIDs = = NULL ) { printf ( "malloc error!\n" ) ; exit ( 1) ; } memcpy ( destIDs, row[ 2] , destNum * sizeof ( uint32_t ) ) ; } mysql_free_result( result) ; printf ( "destNum: %d\n" , destNum) ; temp = destIDs; for ( i= 0; i< destNum; i+ + ) { printf ( "destIDs[%d]:%d\t" , i+ 1, * temp+ + ) ; } return ret; }
由于我这里可以根据 NumDest 获取到二进制的长度,所以不用再用函数去获取。
据网上信息,获取二进制信息长度应该这样:“如果取出来的是二进制的数据 , 要确定它的长度 , 必须要用 mysql_fetch_lengths 函数取得其长度”
int num_fields = mysql_num_fields( result) ; unsigned long * lengths = mysql_fetch_lengths( result) ; for ( i= 0; i< num_fields; i+ + ) printf ( "Column: %u\t %lu bytes\n" , i+ 1, lengths[ i] ) ; destIDs = ( uint32_t * ) malloc ( lengths[ 2] ) ; if ( destIDs = = NULL ) { printf ( "malloc error!\n" ) ; exit ( 1) ; } memcpy ( destIDs, row[ 2] , lengths[ 2] ) ;
才疏学浅,欢迎拍砖! 参考资源:
http://djy0011.blog.163.com/blog/static/138197453201083054918451/