C pass string to query and also check if result is empty - mysql

I need to pass a string to inside the query when connecting to a database using C, but since I have not been using C for a long time I don't know the correct way to do it. I tried the below but that doesn't work.
if (mysql_query(conn, "select * from t1 where c1 = %s and c2 = %s", sptr->name, sptr->desc)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
also what is the easiest method to check whether the query returned an empty result set?

IIRC, you cannot use format specifiers and corresponding arguments directly inside mysql_query() function.
What you need to do is
Allocate one temporary buffer.
use snprintf() to print the query command in the buffer
call mysql_query() with the buffer as second argument.

Related

How to Know records updated with Update query?

How to know whether any record in the table updated with the update query or not.
I am using the Mysql C API..i have tried storing the mysql result after firing the UPDATE query but result is always returning NULL for successful upation also. Any help would be great.
Thanks
int main(void)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
if ((conn = mysql_init(NULL)) == NULL)
{
fprintf(stderr, "Could not init DB\n");
return EXIT_FAILURE;
}
if (mysql_real_connect(conn, "localhost", "root", "password", "cpaas", 0, NULL, 0) == NULL)
{
fprintf(stderr, "DB Connection Error\n");
return EXIT_FAILURE;
}
if (mysql_query(conn, "update calldirection set callid='Hello' where callid='He'") != 0)
{
fprintf(stderr, "Query Failure\n");
return EXIT_FAILURE;
}
res = mysql_store_result(conn);
if(res == NULL){
printf("dssdg");
return 1;
}
if ((row = mysql_num_rows(res)) <= 0)
{
printf("FFFFFFF");
}
mysql_close(conn);
return EXIT_SUCCESS;
}
After Doing Some R&D nearly for 1 day...I found mysql_affected_rows(*mysql) function which will return the number of rows updated for the UPDATE query.
As stated in MySQL mysql-store-resul
After invoking mysql_query() or mysql_real_query(), you must call
mysql_store_result() or mysql_use_result() for every statement that
successfully produces a result set (SELECT, SHOW, DESCRIBE, EXPLAIN,
CHECK TABLE, and so forth). You must also call mysql_free_result()
after you are done with the result set.
You need not call mysql_store_result() or mysql_use_result() for other
statements, but it does not do any harm or cause any notable
performance degradation if you call mysql_store_result() in all cases.
You can detect whether the statement has a result set by checking
whether mysql_store_result() returns a nonzero value (more about this
later)
mysql_store_result returns NULL for the queries other than (SELECT, SHOW, DESCRIBE, EXPLAIN, CHECK TABLE) query types.
and Update query is not one of them, thus mysql_store_result returns NULL for it.

C language variable type float and integer pass in mysql

I'm a beginner in C and mysql programing.For some days now I am trying to write float and integer values that i get from sensors to a database in mySQL.So far i'm just getting an error "too many arguments to function ‘mysql_query’" and " expected ‘const char *’".Below is my simple code.
int main()
{
int var1 = 1;
float var2 = 5.1;
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, "\nError: %s [%d]\n",mysql_error(conn),mysql_errno(conn));
exit(1);
}
printf("Connection successful!\n");
mysql_query(conn,"INSERT INTO variables (var1) VALUE ('%d');",var1);
mysql_query(conn, mysql_query );
}
It's a nice idea, but mysql_query doesn't work with variable arguments.
You need to store the query in a buffer:
char buff[1024];
snprintf(buff, sizeof buff, "INSERT INTO variables (var1) VALUES ('%d');",var1);
and then you can call mysql_query with this buffer:
mysql_query(conn, buff);
EDIT:
As pointed out by #PaulOgilvie: Notice VALUES instead of VALUE in the query.
You should use a prepared statement, which would also take care of the types and all that (assuming conn is a valid connection object)
MYSQL_STMT *stmt;
MYSQL_BIND params[1];
const char *query;
// This is necessary or the program will crash
memset(params, 0, sizeof(params));
query = "INSERT INTO variables (var1) VALUES (?)";
stmt = mysql_stmt_init(conn);
params[0].buffer = &var1;
params[0].buffer_type = MYSQL_TYPE_LONG;
if (stmt == NULL)
exit(1); // Ideally handle the error and solve the problem
// but for simplicity ...
if (mysql_stmt_prepare(stmt, query, strlen(query)) != 0)
exit(1);
if (mysql_stmt_bind_param(stmt, params) != 0)
exit(1);
if (mysql_stmt_execute(stmt) != 0) {
// Ideally print mysql's error
fprintf(stderr, "an error occurred\n");
}
mysql_stmt_close(stmt);
This is the good safe way to do this, and also you can reuse the prepared statement as many times as you want and they promise it will be faster and more efficient because the query is prepared so the execution plan is known and you don't need to use the snprintf() which by the way should be checked for errors and also, you should check if the query did fit into the target array, read the documentation for that.
Also, you don't need to worry about escaping strings or anything. It will all be handled transparently for you. As long as you use the correct type and of course, specify the length of strings.
Note that you can bind parameters and results too in SELECT queries.
Are you sure you don't need "VALUES" here instead of "VALUE":
mysql_query(conn,"INSERT INTO variables (var1) VALUE ('%d');",var1);

MySQL C API mysql_query

I have two problems with the MySQL C API. How do I get variable to be added to the table when I do the mysql_query() and how do I get the table show decimals?
Here is my code:
void insertDataToTable(MYSQL* con, float temp, int k)
{
mysql_query(con, "INSERT INTO Weatherstation VALUES(#k,'Temperature:', #temp)");
}
Thank you!
Try this
void insertDataToTable(MYSQL* con, float temp, int k)
{
char query[255] ;
sprintf( query, "INSERT INTO Weatherstation VALUES(%ld,'Temperature:', %d)", temp, k );
mysql_query(con, query );
}
MySQL does not support host variables that well, the previous answer shows the correct approach in building the query into a string and then using mysql_query(someconnection, string).
What is absolutely shocking is that this is not documented as much as it should be. When I had to learn this I had 30 years of DB2 and C, and I had to get this from GitHub after 2 hours of fruitless searching for "MySQL Host Variables".
You should also be aware of mysql_real_query if your query is not a conventional string and contains embedded nulls, it is passed the length of the string, but can also move a strlen() call off the server.

Using sprintf with mysql_query

I'm using a mysql snippet that connects to my mysql database (locally) in ANSI C. Everything is working perfectly, but I've been trying to create a function that connects to my database and inserts a new record based on some variables. I'm using sprintf to snag those variables and piece them together to form my SQL query.
Problem
Once I have my variables and my SQL ready, I send it over to mysql_query. Unfortunately, this does not work as expected, the program crashes and reports a buffer overflow.
Here are pieces of the overall function that may help explain the problem.
#include <mysql.h>
#include <string.h>
#include <stdio.h>
char *table = "test_table"; // table is called test_table
char *column = "value"; // column is called value
char *value = "working"; // what value we are inserting
char *query; // what we are sending to mysql_query
sprintf(query, "INSERT INTO %s (%s) VALUES ('%s')", table, column, value);
if (mysql_query(conn, query)) {
fprintf(stderr, "%s\n", mysql_error(conn));
return;
}
Purpose
The purpose of the overall function is so I don't have to keep rewriting SQL insert or update statements in my program. I want to call to one function and pass a few parameters that identify the table, columns and the values of said columns.
Any help would be most appreciated. I'm a bit rusty in C these days.
Question
Why is mysql_query not able to send the string?
Changes
This worked based on the comments.
const char *query[MAX_STRING_LENGTH];
sprintf((char *)query, "INSERT INTO %s (%s) VALUES ('%s')", table, column, value);
if (mysql_query(conn, (const char *)query)) {
You have no backing storage for query.
It's either set to NULL or some indeterminate value, depending on its storage duration, neither of which will end well :-)
Quick fix is to change it to
char query[1000];
though any coder worth their salary would also check to ensure buffer overflow didn't occur.

MySQL C API using results

I am using the MySQL C API to query the database and I have the results stored in MYSQL_ROW types. I am able to print the results to the console with
printf("%s", row[0]);
however, according to the MySQL C API documentation, I cannot use them as null-terminated strings.
At the bottom of the function overview, they say I can "extract" the information with mysql_store_result() or mysql_use_result(). However, I am still confused as to how this is done.
Ideally, I want to use the results as a string so I can do stuff like strcmp, but otherwise I definitely need to use the information somehow with those two functions.
Can somebody show me an example of how to do this?
Basically, you call mysql_store_result() or mysql_use_result() to access the result set, the former loads all the rows into memory on the client side, the latter accesses rows one at a time from the server. If you use mysql_use_result(), you need to call mysql_fetch_row() to access each row until the function returns NULL. Each successful call to mysql_fetch_row() will return a MYSQL_ROW which you can use to access the individual field values.
Since the fields are not nul-terminated, you need to use mysql_fetch_lengths() to get the lengths of each of the fields so that you can copy them somewhere else via memcpy, etc.
Since the field values are not nul-terminated you will need to add your own NUL character when you make the copy if you want to use it as a string. Be aware that the field values may contain binary data, so if you do treat it as a string, functions that expect a C string will stop processing data if it encounters a nul-character in the data.
Here is an example from the documentation that should help you put all this together:
MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;
num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result)))
{
unsigned long *lengths;
lengths = mysql_fetch_lengths(result);
for(i = 0; i < num_fields; i++)
{
printf("[%.*s] ", (int) lengths[i],
row[i] ? row[i] : "NULL");
}
printf("\n");
}