[英]Inserting an array of 16-bit ints to MySQL, from C
我需要將大量的int16_t放入MySQL數據庫。 我通過將值復制到char緩沖區來構造查詢字符串,但最后它不起作用(char為1字節,int16_t為2字節。)我在網上找到的有關將數組插入MySQL的文檔可以這樣做。與字符數組。
如何將此int16_t數組插入MySQL數據庫?
我認為您應該查看BLOB數據類型。 可以將二進制數據塊存儲到列中。 根據您所需的大小,有4種不同的口味。 看下面的示例,其中圖像存儲在數據庫中:
真正有趣的部分是頁面的大約80%,該頁面用於存儲圖像,然后從數據庫中檢索圖像。 請特別注意mysql_real_escape_string()函數,該函數可確保數據對於實際查詢是合法的。 您應該能夠立即發送int16數組。
編輯...這是有效的“保存”路由。 它將ints數組作為二進制blob保存到數據庫中。 該程序不完整。 例如。 它沒有連接到數據庫,
#define SIZE 20000
int16_t ints[SIZE];
MYSQL *con;
int
ints_saved(void) // Returns 0 if there's an error
{
char *chunk, *st, *query;
size_t ints_size = sizeof(ints),
st_len;
int qlen;
chunk = (char *)malloc(ints_size*2 + 1);
// template for creating SQL
st = "insert into Ints(Id, Data) values(1, '%s')";
st_len = strlen(st);
// Remove dangerous characters
mysql_real_escape_string(con, chunk, (char *)ints, ints_size);
query = (char *)malloc(st_len + 2*ints_size+1);
// Construct the actual query here
qlen = snprintf(query, st_len + 2*ints_size+1, st, chunk);
printf("%s\n", query);
// Execute the query
if (mysql_real_query(con, query, qlen)) {
printf("%s\n", mysql_error(con));
return(0);
};
return(1);
}
請注意,數據庫表由兩列Id(int)和Data(blob)定義。 如果您還有其他尺寸要求,則可能必須修改Blob。
警告:還沒有人大喊大叫,但請注意該系統在不同的編譯器中可能產生不同的結果。 一些編譯器可能會將16位整數與4字節邊界對齊。 因此,盡管我已使用sizeof()函數將其考慮在內,但實際保存的記錄可能會在某些計算機上占用更多空間。 如果要避免該問題,可以使用“打包”記錄來避免這種情況-請參閱編譯器的文檔。
寫入過程:int16_t位於數組中。 如果將其視為整數,則會得到:
17767 9158 -26519 18547 -9135 23807 -27574 22764 7977 31949 22714 -10325 16882 7931 -22045 -7866 124 25282 2132 10232 8987 -5656 -12825 17293
查看與字節(或字符)相同的數組,我看到:
67 45 C6 23 69 98 73 48 51 DC FF 5C 4A 94 EC 58 29 1F CD 7C BA 58 AB D7
(67 45是第一個int值17767)
我不能這樣寫,因為字節11是0x5C,這混淆了查詢字符串:
67 45 C6 23 69 98 73 48 51 DC FF 5C 4A 94 EC 58 29 1F CD 7C BA 58 AB D7
^^
因此,我調用mysql_escape函數,並使用結果構成查詢:
67 45 c6 23 69 98 73 48 51 dc ff 5c 5c 4a 94 ec 58 29 1f cd 7c ba 58 ab
^^^^^
注意額外的0x5c嗎?
當我執行查詢時,我將轉義的字符串發送給MySQL,MySQL 立即刪除轉義並將UN-ESCAPED字符串寫入數據庫。 因此,從現在開始,不再有多余的0x5c字符。 如果您將其讀回,則數據將再次為“純”數據。
一個非常簡約的例子。 假設我只想向一個表寫入一個0x5c:
我不能寫: insert into Ints(Id, Data) values (1, '\\')
因為MySQL會認為我在\\之后轉義了'。 (請記住,“ \\”是0x5c)
所以我逃避了\\: insert into Ints(Id, Data) values (1, '\\\\')
。 當MySQL收到此查詢時,盡管它只插入一個 \\。
在表中僅插入一個字符。 當回讀時,它僅產生一個字符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.