从C插入一个16位整数的数组到MySQL

时间:2014-12-22 02:50:37

标签: mysql c

我有一大堆int16_t需要放入MySQL数据库。我通过将值复制到char缓冲区构建了一个查询字符串,但最后它不起作用(char是1个字节,int16_t是两个字节。)我在网上找到的关于向MySQL插入数组的文档是这样的用字符数组。

如何将这个int16_t数组插入MySQL数据库?

1 个答案:

答案 0 :(得分:1)

我认为你应该看一下BLOB数据类型。它可以将二进制数据块存储到列中。根据您需要的尺寸,有4种不同的口味。看看以下示例,其中图像存储在数据库中:

http://zetcode.com/db/mysqlc/

真正有趣的部分是页面中约80%的下降,其中存储图像并随后从数据库中检索。特别注意 mysql_real_escape_string()函数,用于确保数据对于实际查询是合法的。您应该能够立即发送int16数组。

编辑......以下是“保存”路由。它保存了int数组 作为二进制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()函数考虑在内,但实际保存的记录可能会在某些机器上占用更多空间。如果您想避免这个问题,可以使用'packed'记录来避免这种情况 - 请参阅编译器的文档。

过程: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收到此查询时,它只插入一个 \。

在表格中只插入一个字符。回读时,它只产生一个字符。