我使用以下代碼將任意二進制數據插入到mysql數據庫MEDIUMBLOB中。我從相同的程序將相同的數據寫入文件。我再從DB內容創建一個文件:將字符插入到數據庫中
select data from table where tag=95 order by date, time into outfile "dbout";
我再比較直接寫入文件中DBOUT輸出的輸出。在dbout文件中的某些字節(例如0x00之前)之前有escape(0x5c,'\')字符。這會干擾數據庫的輸出。我的理解是,通過使用MEDIUMBLOB並準備好語句,我可以避免這個問題。最初我使用了帶有普通INSERT的mysql_real_escape_string,並且遇到了問題。似乎沒有什麼解決這個問題的。
void
insertdb(int16_t *data, size_t size, size_t nmemb)
{
int16_t *fwbuf; // I have also tried this as char *fwbuf
unsigned long i;
struct tm *info;
time_t rawtime;
char dbuf[12];
char tbuf[12];
if(fwinitialized==0){
fwbuf = malloc(CHUNK_SZ);
fwinitialized = 1;
}
if(fwindex + (nmemb*size) + 1 >= CHUNK_SZ || do_exit == 1){
MYSQL_STMT *stmt = mysql_stmt_init(con);
MYSQL_BIND param[1];
time(&rawtime);
info = localtime(&rawtime);
snprintf(dbuf, 16, "%d-%02d-%02d", 1900+info->tm_year, 1+info->tm_mon, info->tm_mday);
snprintf(tbuf, 16, "%02d:%02d:%02d", info->tm_hour, info->tm_min, info->tm_sec);
char *tmp = "INSERT INTO %s (date, time, tag, data) VALUES ('%s', '%s', %d, ?)";
int len = strlen(tmp)+strlen(db_mon_table)+strlen(dbuf)+strlen(tbuf)+MAX_TAG_LEN+1;
char *sql = (char *) malloc(len);
int sqllen = snprintf(sql, len, tmp, db_mon_table, dbuf, tbuf, tag);
if(mysql_stmt_prepare(stmt, sql, strlen(sql)) != 0){
printf("Unable to create session: mysql_stmt_prepare()\n");
exit(1);
}
memset(param, 0, sizeof(param));
param[0].buffer_type = MYSQL_TYPE_MEDIUM_BLOB;
param[0].buffer = fwbuf;
param[0].is_unsigned = 0;
param[0].is_null = 0;
param[0].length = &fwindex;
if(mysql_stmt_bind_param(stmt, param) != 0){
printf("Unable to create session: mysql_stmt_bind_param()\n");
exit(1);
}
if(mysql_stmt_execute(stmt) != 0){
printf("Unabel to execute session: mysql_stmt_execute()\n");
exit(1);
}
printf("closing\n");
mysql_stmt_close(stmt);
free(sql);
fwindex = 0;
} else {
memcpy((void *) fwbuf+fwindex, (void *) data, nmemb*size);
fwindex += (nmemb*size);
}
}
那麼,爲什麼數據庫中的轉義字符?我已經在程序中以及從msyql創建文件時嘗試了幾個hex/unhex的組合。這似乎也沒有幫助。是不是將一個任意的二進制數據插入到數據庫中是一個定義明確的解決方案的常見事情?
P.S. - 可以準備好打開,插入和關閉這樣的語句,或者準備好通常用於在關閉之前循環和插入一堆數據的語句?
PPS - 也許這是解決問題的重要:當我嘗試使用UNHEX這樣的:
select unhex(data) from table where tag=95 order by date, time into outfile "dbout";
輸出很短(不到幾十個字節,截斷由於某種原因)。
你的代碼有很多問題,最不重要的是顯示'tag'是什麼,而最糟糕的是可能的[undefined behavior](http://en.wikipedia.org/wiki/Undefined_behavior)不在字符串中爲字符串終止符分配空間。 –
什麼是標籤的數據類型?注意sizeof(tag)對於數字的字符串長度表示來說不是一個好的估計。如果標籤是一個指針,它將是8或4字節(取決於你是否編譯爲32或64位體系結構),無論存儲的數字是多少,例如數字「1」只有長度1 ..還有一些內存泄漏在你的程序中。特別是在你的錯誤處理代碼中,你不會在退出之前釋放sql或fwbuf。 – Rob
@Rob - 標記只是一個int。另外,如果程序退出,我認爲sql和fwbuf將被操作系統「釋放」。但是,如果我的問題沒有轉義字符存儲任意二進制數據在數據庫中? –