【问题标题】:How do I insert data into mysql table?如何将数据插入mysql表?
【发布时间】:2016-07-06 12:37:49
【问题描述】:

我正在尝试将数据插入 mysql 数据库。数据的连接和显示工作。

但我不知道如何在 C 代码中使用 INSERT INTO table 命令。

我尝试将带有scanf/getchar 的字符串读取到mysql 命令中的值,但没有成功。

在我的程序中读取数据后如何往mysql表中插入数据?

我在 Linux 中工作。

这是我的源代码:

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>

static char *host = "localhost";
static char *user = "root";
static char *pass = "PASSWORD";
static char *dbname = "tutorial";

unsigned int port = 3306;
static char *unix_socket = NULL;
unsigned int flag = 0;

int main()
{
MYSQL *conn;
MYSQL_RES * res;
MYSQL_ROW row;
conn = mysql_init(NULL);

if(!(mysql_real_connect(conn, host, user, pass, dbname, port, unix_socket, flag)))
{
    fprintf(stderr, "Error: %s[%d]", mysql_error(conn), mysql_errno(conn));
    exit(1);
}

mysql_query(conn, "SELECT * FROM users");
res = mysql_store_result(conn);


while(row = mysql_fetch_row(res))
{
    printf("%s\t%s\n", row[0], row[1]);
}

mysql_free_result(res);
mysql_close(conn);

return EXIT_SUCCESS;
}

我试过了:

...
int id[1] = 5;
char name[8] = "Jack";
...
mysql_query(conn, INSERT INTO users(id, name) VALUES(id, name);
...

【问题讨论】:

  • 尝试时会发生什么?有错误吗?
  • 不是错误,只是没有。

标签: mysql c linux


【解决方案1】:

您必须在创建查询之前准备好 C 字符串。

您可以使用snprintf 这样做:

#define MAX_STRING 128
char query[MAX_STRING] = {0};
int id = 5;
char name[] = "jack";

snprintf(query, MAX_STRING, "INSERT INTO users (id, name) VALUES (%d, '%s')", id, name);

mysql_query(conn, query);

正如@viraptor 指出的上面的解决方案存在 sql 注入问题。 您应该使用 mysql api(编码为完全安全)来完成这项工作:

#define INSERT_QUERY = "INSERT INTO users (id, name) VALUES (?,?)";

int id = 5;
char name[] = "jack";
size_t str_length = strlen(name);

MYSQL_STMT *stmt = mysql_stmt_init(mysql);
if (!stmt)
{
   fprintf(stderr, " mysql_stmt_init(), out of memory\n");
     exit(0);
}
if (mysql_stmt_prepare(stmt, INSERT_QUERY, strlen(INSERT_QUERY)))
{
   fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}

MYSQL_BIND bind[2];

/* INTEGER PARAM */
/* This is a number type, so there is no need
   to specify buffer_length */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&id;
bind[0].is_null= 0;
bind[0].length= 0;

/* STRING PARAM */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)name;
bind[1].buffer_length= str_length+1;
bind[1].is_null= 0;
bind[1].length= &str_length;

/* Bind the buffers */
if (mysql_stmt_bind_param(stmt, bind))
{
  fprintf(stderr, " mysql_stmt_bind_param() failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

/* Execute the INSERT statement - 2*/
if (mysql_stmt_execute(stmt))
{
  fprintf(stderr, " mysql_stmt_execute, 2 failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

/* Get the total rows affected */
my_ulonglong affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, " total affected rows(insert 2): %lu\n",
                (unsigned long) affected_rows);

if (affected_rows != 1) /* validate affected rows */
{
  fprintf(stderr, " invalid affected rows by MySQL\n");
  exit(0);
}

/* Close the statement */
if (mysql_stmt_close(stmt))
{
  fprintf(stderr, " failed while closing the statement\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

您可以找到此代码的参考at this link

【讨论】:

  • 否决,因为这有 sql 注入的问题。 mysql 有用于传递值的 api - 它是准备好的语句:dev.mysql.com/doc/refman/5.7/en/mysql-stmt-execute.html
  • @viraptor 好吧,用文字字符串执行的所有类型的代码都可以很容易地被破解。顺便说一句,我认为 OP 的情况并非如此简单/基本的代码。
  • 这些字符串目前可能是字面的,但将来可能不是。 “现在可以”或“即使您更改参数也可以”更好的选择是什么?现在是 2016 年,人们仍然经常无法解决此类问题。让我们至少让不安全的例子远离 SO。如果 Onur 有这样的基础问题,我宁愿他尽快了解注射。
  • @viraptor 好吧,我完全同意。我的错。希望我的编辑是好的。
  • 我是 C 中的 mysql 编程初学者。在 C# 中很容易,但这很难。谢谢你的回答,我正在努力。
【解决方案2】:

查看https://dev.mysql.com/doc/refman/5.7/en/mysql-stmt-execute.html 的示例,了解如何执行此操作。

总而言之,您创建一个准备好的语句,使用mysql_stmt_prepare 对其进行初始化,然后通过mysql_stmt_bind_param 传递值。

您还可以使用https://dev.mysql.com/doc/refman/5.7/en/mysql-real-escape-string-quote.html 引用的值构造查询的文本版本,但在这种情况下很容易意外跳过某些元素。

【讨论】:

  • 不是DV,但这个答案似乎属于link only answer
  • @LPs 该示例有 30 多行。我试图总结所涉及的功能,以便于查找。如果您可以在这里制作一个有意义的简短示例,请随时提出修改建议或回答自己:)
  • 我编辑了我的答案。看看有没有问题。泰。
  • 在您的第一个链接中,是不是太长了?只是插入数据而已,不可能这么长这么复杂。
  • @OnurTuralı 这有点冗长。但无论如何,他们都会做所有你想做的错误检查。绑定参数的结构是在代码本身中定义的,但您可以在文件顶部定义它们,例如MYSQL_BIND params[] = {{.buffer_type=..., .is_null=...}, {.buffer_type=..., ...},这样会更简洁。
猜你喜欢
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 2015-01-09
相关资源
最近更新 更多