2016-07-06 4 views
0

Я пытаюсь вставить данные в базу данных mysql. Соединение и отображение данных работают.Как вставить данные в таблицу mysql?

Но я не знаю, как использовать команду INSERT INTO table в коде C.

Я попытался считывать строки с 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); 
... 
+0

Что происходит, когда вы пытаетесь? Есть ли ошибка? – Taegost

+0

Не ошибка, просто ничего. –

ответ

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

+0

Downvoted, потому что это имеет проблемы с SQL-инъекцией. mysql имеет api для передачи в значениях - это подготовленные операторы: https://dev.mysql.com/doc/refman/5.7/en/mysql-stmt-execute.html – viraptor

+0

@viraptor Ну, конечно, все виды кода выполняются с буквальным строки можно легко взломать. Кстати, я не думаю, что это так для OP с таким простым/базовым кодом. – LPs

+0

Строки могут быть буквальными на данный момент, но, возможно, не в будущем. Какой лучший вариант «это нормально сейчас», или «это нормально, даже если вы меняете параметры»? Это 2016 год, и люди по-прежнему постоянно не могут решить такие проблемы. Давайте, по крайней мере, сохраним небезопасные примеры. Если у Онура возникают проблемы с такими основами, я бы предпочел, чтобы он как можно скорее узнал об инъекции. – viraptor

1

взглянуть на примеры в 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, но в этом случае легко случайно пропустить некоторые элементы.

+0

Не DV, но этот ответ, похоже, попадает в _link только answer_ – LPs

+0

@LPs Пример: 30+ строк. Я попытался подвести итог задействованным функциям, чтобы их было легко найти.Если вы можете сделать более короткий пример, который будет иметь смысл здесь, не стесняйтесь предлагать редактирование или отвечать самостоятельно :) – viraptor

+0

Я отредактировал свой ответ. Посмотрите, если что-то не так. Ty. – LPs

Смежные вопросы