c mysql 存取二进制_mysql存取二进制数据

1 -- 存取二进制数据可行性分析

考虑1:函数mysql_query存储二进制数据,可行不?也行也不行,比如SQL语句中恰好含有'\0',而mysql_query又是以'\0'表示SQL语句结束,这样SQL语句被截断就不完整了。查看帮助发现还有一个mysql_real_query,最妙的是它不是使用'\0'终结SQL,而是用一个整形数表示SQL语句的长度。

考虑2:函数mysql_real_query规避了'\0'可能引起的麻烦。如果SQL中的二进制数据是“'”、“"”这些特殊字符呢?看来还得用mysql_real_escape_string过滤下,才能放心使用。

考虑3:经过上面的两步后,存储二进制数据基本上没什么问题。那怎么将其读出来呢?如果直接将读出的数据赋值给string,有可能被截断。解决方法是,先调用mysql_fetch_lengths获得值的长度,然后按长度copy数据。

2 -- 实例程序

三个关键函数:

int mysql_query(MYSQL *mysql, const char *query);

int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);

unsigned long mysql_real_escape_string(MYSQL *mysql, char *d, const char *s, unsigned long len);

#include

#include

#include "mysql.h"

const std::string Escape(MYSQL * pHandle, const std::string & sFrom)

{

std::string::size_type iLen = sFrom.size() * 2 + 1;

char * pTo = (char *)malloc(iLen);

memset(pTo, 0x00, iLen);

unsigned long lEscLen = mysql_real_escape_string(pHandle, pTo, sFrom.data(), sFrom.size());

std::string sTo(pTo, lEscLen);

free(pTo);

return sTo;

}

int main()

{

MYSQL * pHandle = mysql_init(NULL);

if (mysql_real_connect(pHandle, "127.0.0.1", "user", "pass", "base", 1206, NULL, 0) == NULL)

{

std::cout << "connect fail" << std::endl;

return -1;

}

{

std::string sTemp("aaa\0bbb", 7); sTemp = Escape(pHandle, sTemp);

std::string sFrom("INSERT INTO t_testsz(myname, mytext) VALUES('name', '");

sFrom.append(sTemp.data(), sTemp.size());//这一步放入一个二进制的数据

sFrom.append("')");

if (mysql_real_query(pHandle, sFrom.data(), sFrom.size()) != 0)

{

std::cout << "mysql exec fail:" << mysql_error(pHandle) << std::endl;

return -1;

}

}

{

std::string sFrom("SELECT myname, mytext FROM t_testsz");

if (mysql_real_query(pHandle, sFrom.data(), sFrom.size()) != 0)

{

printf("%s\n%s", sFrom.c_str(), mysql_error(pHandle));

return -1;

}

MYSQL_RES * pRes = mysql_store_result(pHandle);

for (MYSQL_ROW stRow = NULL; (stRow = mysql_fetch_row(pRes)) != NULL; )

{

unsigned long * lengths = mysql_fetch_lengths(pRes);

std::string sName; sName.append(stRow[0], lengths[0]);

std::string sText; sText.append(stRow[1], lengths[1]);

std::cout << "Name:" << sName << "|size:" << sName.size() << std::endl;

for (std::string::size_type i = 0; i < sName.size(); i++)

{

printf("%02X%c", sName[i], (i == sName.size() - 1?'\n':' '));

}

std::cout << "Text:" << sText << "|size:" << sText.size() << std::endl;

for (std::string::size_type i = 0; i < sText.size(); i++)

{

printf("%02X%c", sText[i], (i == sText.size() - 1?'\n':' '));

}

}

}

return 0;

}

makefile文件:

INCLUDE := -I/usr/local/mysql/include/mysql

LIB := -L/usr/local/mysql/lib/mysql -lmysqlclient

all : main

main : main.cpp

g++ -Wall -o main main.cpp ${INCLUDE} ${LIB}

clean :

rm -rf main *.o

建表SQL语句:

CREATE TABLE `t_testsz` (

`id` int(11) NOT NULL auto_increment,

`myname` varchar(200) NOT NULL default '',

`mytext` varchar(200) NOT NULL default '',

PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=gbk

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值