Inserting strings as values in mysql queries - mysql

I want to make Inserts on mysql database,having as values,some string,chars...
This works:
if (mysql_query(con, "INSERT INTO Cars VALUES(2,'Mercedes',57127)")) {
finish_with_error(con);
}
How can I do something like this?
char str[]="Mercedes";
if (mysql_query(con, "INSERT INTO Cars VALUES(2,str,57127)")) {
finish_with_error(con);
}
In working in C.

You need to concatenate the two "strings" before passing them down into the library.
Either using the pre-processor:
#define str "Mercedes"
...
if (mysql_query(con, "INSERT INTO Cars VALUES(2,"str",57127)")) {
finish_with_error(con);
}
Or do it during runtime:
char str[] = "Mercedes";
char query_template[] = "INSERT INTO Cars VALUES(2,%s,57127)"
char query[sizeof str + sizeof query_template - 3];
sprintf(query, query_template, str);
if (mysql_query(con, query, )) {
finish_with_error(con);
}
Note: The latter solution introduces a security issue if the content of str is provided externally. Do not do this in production code then.

try this
int id=1,price=123435;
char name[]="mercedez";
char consulta[1024];
sprintf(consulta,"insert into cars values('%d','%s','%d')",id,name,price);
if(mysql_query(con,consulta)==0)
fprintf(stdout,"datos insertados con exito\n");

Try this:
char str[] = "Mercedes";
response = mysql_query("INSERT INTO cars (column1,column2,column3) VALUES 2,'str',57127)");
if(response){ finish_with_error(con); }

Related

Store binary data structure into BLOB columns in C

I load a dictionary and made many manipulation in it. To save some CPU time, I actually store the result into a flat file for future use. How can I store that memory structure into a BLOB columns of MariaDB database (program in C)
He is my actual code et what an example of what I try to do.
//--- Global variables and CONST for databases
#define DB_NAME "some_name"
#define DB_USER "admin"
#define DB_PWD "qwerty"
#define DB_SERVER "localhost"
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
int main (int argc, char **argv)
{
char str_query [2048] ;
//----------------------------------------------------------------
// The way I dump the memory (structure) into a flat file actually
//----------------------------------------------------------------
fd = fopen("./mem_dump.binary","wb");
fwrite(&st_dic, sizeof(struct Dictionary), 1, fd);
fclose (fd);
//----------------------------------------------------------------
// The way I need to do it
// Insert the structure into a BLOB column
//----------------------------------------------------------------
conn = mysql_init(NULL);
if (!mysql_real_connect(conn, DB_SERVER, DB_USER, DB_PWD, DB_NAME, 0, NULL, 0))
{
fprintf(stderr, "ERROR:%s\n", mysql_error(conn));
exit (1) ;
}
//....
sprintf (str_query, "INSERT INTO myTables (id, blob_field) VALUES (0, '%s')", &st_dic) ;
//....
if (mysql_query(conn, str_query))
{
fprintf(stderr,"FAIL TO RUN SQL : [%s]\n", str_query) ;
fprintf(stderr, "%s\n", mysql_error(conn));
}
mysql_free_result(res);
mysql_close(conn);
return (0) ;
}
When working with binary objects text protocol (mysql_query/mysql_real_query) is not the best option, since special characters like '\0' are not supported. That means you have to allocate additional buffer (2 * (size of blob) + 1) for transforming the binary object.
Solution 1: mysql_real_escape()
char *buffer = malloc(sizeof(struct Dictionary) * 2 + 1);
mysql_real_escape_string(conn, buffer, &st_dic, sizeof(struct Dictionary));
sprintf(str, "INSERT INTO myTables (id, blob_field) VALUES (0, '%s')", buffer);
if (mysql_query(conn, str))
{
/* Error handling */
}
Solution 2: mysql_hex_string()
char *buffer = malloc(sizeof(struct Dictionary) * 2 + 1);
mysql_hex_string(buffer, &st_dic, sizeof(struct Dictionary));
sprintf(str, "INSERT INTO myTables (id, blob_field) VALUES (0, X'%s')", buffer);
if (mysql_query(conn, str))
{
/* Error handling */
}
Alternative:
A better solution is to use prepared statements which use the binary protocol:
Code without error handling:
MYSQL_BIND bind;
MYSQL_STMT *stmt;
stmt= mysql_stmt_init(conn);
mysql_stmt_prepare(stmt, INSERT INTO myTables (id, blob_field) VALUES (0, ?)", 1);
memset(&bind, 0, sizeof(MYSQL_BIND));
bind.buffer_type= MYSQL_TYPE_BLOB;
bind.buffer= &st_dic;
bind.buffer_length= sizeof(struct Dictionary);
mysql_stmt_bind_param(stmt, &bind);
mysql_stmt_execute(stmt);

C - alternative using snprintf to prepare MySQL statements?

I've been tearing my hair out for a while on this one. The C code is called from a bash script, which loops through a command's output in a while loop and passes variables to the C script as args. It goes through a list and partitions data properly. I've been using the C MySQL api, and up until now everything has been relatively straight forward. It tries to run a SELECT(EXISTS) command to dictate whether to input a new row, or update an existing one.
I have typed the command into MySQL terminal and it works perfectly. I have even printf'd it and copied the command directly into the terminal. It works....
So why then, am I getting Syntax errors? I've tried escaping fields and input using backticks, single quotes and double quotes and I'm still getting this dumbounding error. I thought maybe it was something to do with the null space? But I'm at my witts end. Here's the code, any advice would be greatly appreciated :)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mysql/mysql.h>
const int MAXLEN = 100;
/* Compile with:
gcc db.connect.c `mysql_config --libs` -O1
for the best results
*/
/* Function definitions for later */
void finish_with_error(MYSQL *con);
int send_query(MYSQL *con, char query[MAXLEN]);
/* If any SQL commands fail, return an error message */
void finish_with_error(MYSQL *con)
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
/* Helper function to send queries to MySQL database */
int send_query(MYSQL *con, char query[MAXLEN])
{
if (mysql_query(con, query)) {
finish_with_error(con);
}
return 0;
}
int main(int argc, char ** argv)
{
// Establish MySQL API connection, if not- fail with err
MYSQL *con = mysql_init(NULL);
if (con == NULL) {
finish_with_error(con);
}
// Connection string.
if (mysql_real_connect(con, "localhost", "user", "password",
NULL, 0, NULL, 0) == NULL){
finish_with_error(con);
}
if (argv[1] == NULL){
printf("No query passed, terminating script \n");
return 1;
}
if (argv[1] != NULL) {
if( strcmp( argv[1], "--help" ) == 0 ) {
printf("This program was created to interact with MySQL, by checking and updating live network stats\n");
printf("It has 2 parameters, an IP address to look in the database for and a value to update a field by, \
if that IP address is found. ");
printf("If the value is not found, the program will insert a new row.");
return 1;
}
// Works out how much memory to allocate to buffer for snprintf
// Originally cmd_len was 65- as this was the amount of bits needed by the address string.
// This was changed to MAXLEN to prevent SEGFAULTS and give the function breathing room.
size_t cmd_len = MAXLEN;
size_t param_len = sizeof(argv[2]);
size_t q_len = cmd_len + param_len;
// Allocates that memory to a buffer, referenced as query
char *query = malloc(sizeof(char) * q_len);
snprintf(query, q_len, "SELECT EXISTS(SELECT * FROM `analytics`.`live` WHERE `foreign_addr` = `%s`)", argv[1]);
printf("%s\n", query);
send_query(con, query);
free(query);
// Used to store the result of the MySQL select commands
MYSQL_RES *result = mysql_store_result(con);
if (result == NULL) {
finish_with_error(con);
}
// num_fields stores the number of fields, i and x are counters, answer is 1 or 0
int num_fields = mysql_num_fields(result);
int i = 0;
// Loops through each row in the answer statement.
// There will only be one row in the answer, which will be 1 or 0
// Basically, if the IP is found.
MYSQL_ROW row;
while ((row = mysql_fetch_row(result))){
for (i=0; i<num_fields; i++) {
// If the IP isn't in the table
if(!atoi(row[i]))
send_query(con, argv[1]);
// If the IP is already in the table
if(atoi(row[i])) {
snprintf(query, q_len, "UPDATE analytics.live SET count=count+1 WHERE foreign_addr = '%s'", argv[1]);
printf("%s\n", query);
free(query);
snprintf(query, q_len, "UPDATE analytics.live SET dat_sent = dat_sent + %s", argv[2]);
printf("%s\n", query);
free(query);
}
}
}
mysql_close(con);
return 1;
}
mysql_close(con);
return 0;
}

MySQL command to delete a row in C is not working

I don't usually code using C programming language but I learned it in school (so please bear with me because I am still a newbie).
In short, I was recently assigned to write code in C in order to delete rows from a table in MySQL database.
I used stackoverflow and other resources to help me with this code!
This is my code (not all of it):
void delete_rows(MYSQL *con)
{
char selection_query[256];
char deletion_query[256];
sprintf(selection_query, "SELECT id FROM <table> WHERE status = 'PROCESSING'\
AND started < DATE(NOW()) - INTERVAL %d DAY", expire_processing_days);
if (mysql_query(con, selection_query))
{
finish_with_error(con);
}
MYSQL_RES *result = mysql_store_result(con);
if (result == NULL)
{
finish_with_error(con);
}
int num_fields = mysql_num_fields(result);
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)))
{
for(int i = 0; i < num_fields; i++)
{
printf("Deleting process with id: %s ", row[i] ? row[i] : "NULL");
sprintf(deletion_query, "DELETE FROM <table> WHERE id = %d", row[i]);
if (mysql_query(con, deletion_query))
{
finish_with_error(con);
}
mysql_commit(con);
}
printf("\n");
}
mysql_free_result(result);
}
int main()
{
MYSQL *con;
DB_CONN_PARAMS *params = calloc(1,sizeof(DB_CONN_PARAMS));
//just an alternative way of passing connection params, find a struct easier
strcpy(params->host, <host>);
strcpy(params->user, <user>);
strcpy(params->pass, <password>);
strcpy(params->db, <database>);
MYSQL * connect_db(DB_CONN_PARAMS *params);
con = connect_db(params);
//we don't need the struct anymore
free(params);
params = NULL;
//kill processes that are incomplete/hanging
delete_rows(con);
//close mysql connection
mysql_close(con);
return EXIT_SUCCESS;
}
So, the code above compiles and runs without any errors, it prints out the ids of the rows that I want to delete. But when I go to the database to check the rows, they are still there!
Is there anything I am missing?
Ok, I have figured it out finally!
I changed the %d to %s in the following line:
sprintf(deletion_query, "DELETE FROM WHERE id = %d", row[i]);.
Because row[i] is a string, I was blind to that.
I was able to figure it out by printing the whole MySQL command and noticed that the id passed is wrong!
Thank you everyone for your attempts to help me.

C program to add data to MYSQL database - No results added

I'm trying to build a C-program to add data to my MYSQL database and I would like to use variables within the SQL string. I want to insert UNIX time (epoch) in one column and the result from an energy meter into the other (double)
Even though it builds without errors or warnings I can't get it to insert the data into the table. Can someone give me a hint of where to look?
Thankful for all help I can get as I'm pretty much fumbling in the dark
Regards,
Mikael
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <mysql.h>
#include <my_global.h>
#include <stdlib.h> // For exit function
int loggingok; // Global var indicating logging on or off
double result = 323.234567; //Debug
double actual_time_sec;
void calculate_watts(void)
{
MYSQL *conn = mysql_init(NULL);
char *server = "localhost";
char *user = "root";
char *password = "password"; /* set me first */
char *database = "power";
char SQL_String[100];
char time_char[11];
char result_char[11];
time_t actual_time;
actual_time = time(0);
actual_time_sec = difftime(actual_time,0);
sprintf(time_char,"%g",actual_time_sec);
sprintf(result_char,"%g",result);
printf("Tid: %g\n",actual_time_sec); //Debug
printf("Resultat: %g\n", result); //Debug
strcpy(SQL_String, "INSERT INTO consumption(time,consumption) VALUES(");
strcat(SQL_String, time_char);
strcat(SQL_String, ",");
strcat(SQL_String, result_char);
strcat(SQL_String, ")");
printf("SQL: %s", SQL_String); //Debug
// SQL_String = "INSERT INTO consumption(time,consumption) VALUES('"+ actual_time_sec +"',"+ result +")";
if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1); }
if (mysql_query(conn, SQL_String)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1); }
}
int main (int argc, char *argv[])
{
printf(argv[1]); //Debug
if(strcmp(argv[1], "db")) {
loggingok=1;
printf("Efergy E2 Classic decode \n\n");
calculate_watts(); }
else {
loggingok=0; }
return 0;
}
here is a great example...
http://php.net/mysql_query. Note the usage of sprintf here. The 2nd and 3rd parameters work with the sprintf to place the data in these 2 parameters exactly where they are needed in the SQL statement.
$query = sprintf("SELECT firstname, lastname, address, age FROM friends
WHERE firstname='%s' AND lastname='%s'",
mysql_real_escape_string($firstname),
mysql_real_escape_string($lastname));
// Perform Query
$result = mysql_query($query);
// Check result
// This shows the actual query sent to MySQL, and the error. Useful for debugging.
if (!$result) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $query;
die($message);
}
Please note the usage of if (!$result) this allows you to do a quick validation of if you have success or not. If an error is found the text resturned from mysql_error is placed in the message variable and then presented when the app dies.

Printing records alternative way

Is there a way to directly display the content of a query in Mysql using C?
What I mean is:
through mysql shell if I type : SELECT * FROM table_name; I get the query result in a neat and formatted way.
If I want to do the same thing using Api C I have to write several lines of codes and the final result is far from being nice (at least this is my personal experience )
For example :
void display_Table1(MYSQL *conn)
{
int jj,ii;
char query[512];
sprintf(query, "SELECT * FROM Table1 ;");
if (mysql_query (conn, query)) {
printf("\nErrore query:\n");
printf("%s", mysql_error(conn),"\n");
result = mysql_store_result(conn);
if (result) {
num_rows = mysql_num_rows(result);
num_fields =mysql_num_fields(result);
//printf("Number of rows=%u Number of fields=%d \n", num_rows,num_fields);
//printf(" ");
}
else
{
printf("Result set is empty");
}
// Print column headers
fields = mysql_fetch_fields(result);
for(jj=0; jj < num_fields; jj++)
{
printf("\n%s\t\t",fields[jj].name);
}
printf("\n\t ");
// print query results
while(row = mysql_fetch_row(result)) // row pointer in the result set
{
for(ii=0; ii < num_fields; ii++)
{
printf("%s\t", row[ii] ? row[ii] : "NULL"); // Not NULL then print
}
printf("\n");
}
if(result)
{
mysql_free_result(result);
result = NULL;
}
}
}
That's a knotty problem to solve. I get headers one after the other in a vertical way.
I also get
Commands out of sync; you can't run this command now
Firstly, there is no direct way to print out a formatted display. What you can do, is use
MYSQL_FIELD *field = mysql_fetch_field (resultset);
col_len = field->max_length;
if(col_len < strlen(field->name))
col_len = strlen(field->name);
to find out the maximum width of a column, and the space the data accordingly.