C Prog Newb: retrieve MYSQL query true/false value - mysql

Will try to make this simple - I can elaborate if needed:
Goal: trying to query MYSQL DB from C if a row or record exists using this command
SELECT EXISTS(SELECT * FROM users WHERE id = '123456789'
these are some of the test codes I've tried to get a proper return value from mysql.
sprintf(exist, "SELECT EXISTS(SELECT * FROM users WHERE id = '%s')", new_person.ID);
printf("\n\nExists result: %s\n\n", (mysql_query(conn, exist))); // debug code - return NULL
printf("\n\nExists = %s\n\n", exist); // debug code - output seems exactly what I want sent to database, I've tested with and without singles quotes ' '
printf("\n\nMYSQL_QUERY: %d\n\n", mysql_query(conn, exist)); // debug code - testing return value - seems all successfull query return 1 - always return 1 regardless if id exists or not.
printf("\n\nSQLSTATE: %d\n\n", mysql_stmt_sqlstate(exist)); // this does not return what's intended - looking for a value of 1 or 0 - returns 12935280
test = mysql_stmt_sqlstate(exist); // debug code testing if correct value is assigned
The goal is to get a return of 1 or 0 from my db. When I query mysql directly, i do get a true or false value as you can see below
mysql> select * FROM users;
+-----------+------------+-----------+------------+--------+--------+------+
| id | first_name | last_name | dob | height | weight | BMI |
+-----------+------------+-----------+------------+--------+--------+------+
| 123456789 | xxxx | xxxxx | xxxxxxxxxx | xx | xxx | xxxx |
| 254565 | Jessica | Perez | 05/03/2001 | 60 | 120 | 23.4 |
| 456132 | Tomas | Aquina | 02/01/1254 | 58 | 140 | 29.3 |
| 5245 | Herlinda | Jones | 12/01/1982 | 69 | 180 | 26.6 |
+-----------+------------+-----------+------------+--------+--------+------+
4 rows in set (0.00 sec)
mysql> SELECT EXISTS(SELECT * FROM users WHERE id = 123456789);
+--------------------------------------------------+
| EXISTS(SELECT * FROM users WHERE id = 123456789) |
+--------------------------------------------------+
| 1 |
+--------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT EXISTS(SELECT * FROM users WHERE id = 6548);
+---------------------------------------------+
| EXISTS(SELECT * FROM users WHERE id = 6548) |
+---------------------------------------------+
| 0 |
+---------------------------------------------+
1 row in set (0.00 sec)
I need the true/false value as a conditional for other parts of the code.
Sorry if this has been addressed or answered before. I couldn't find it anywhere and I looked in MySQL reference at: https://dev.mysql.com/doc/c-api/8.0/en/c-api-function-reference.html
Thanks again!
For those who want to see the full code:
// 911Prep - software to track of household emergency needs
// Hans Yunge (C)2022
#define _CRT_SECURE_NO_WARNINGS
// header inclusions
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <mysql.h>
#include "911prep_header.h"
// function declaration
void create_person(Person* new_person);
int main(int argc, char** argv) {
char *query;
char* exist;
// calling creating Person function - printing out data
Person new_person;
Person_p ptr_person = &new_person;
create_person(ptr_person);
// BMI calculation
new_person.BMI = new_person.weight / (new_person.height * new_person.height) * 703;
// connect to mysql
MYSQL* conn;
MYSQL_RES* res;
MYSQL_ROW row;
char* server = "localhost";
char* user = "root";
char* password = "password"; // set me first
char* database = "911prep";
conn = mysql_init(NULL);
if (conn == NULL) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
// Connect to database
if (!mysql_real_connect(conn, server,
user, password, NULL, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
if (mysql_query(conn, "CREATE DATABASE IF NOT EXISTS testdb"))
{
fprintf(stderr, "%s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
printf("\nMySQL version is: %s\n", mysql_get_client_info());
// select database
if (mysql_query(conn, "USE 911prep"))
{
fprintf(stderr, "%s\n", mysql_error(conn));
}
// check to see if row exists and update data to existing row
query = (char*)malloc(200);
exist = (char*)malloc(50);
sprintf(exist, "SELECT EXISTS(SELECT * FROM users WHERE id = '%s')", new_person.ID);
printf("\n\nExists result: %s\n\n", (mysql_query(conn, exist)));
printf("\n\nExists = %s\n\n", exist);
printf("\n\nMYSQL_QUERY: %d\n\n", mysql_query(conn, exist)); // testing return value - seems all successfull query return 1
int test = mysql_stmt_sqlstate(exist); // this does not return what's intended - looking for a value of 1 or 0
if (test == 1)
{
sprintf(query, "UPDATE users SET first_name ='%s', last_name = '%s', dob = '%s', height = %2.0f, weight = %3.0f, BMI = %2.1f WHERE id=%s", new_person.firstName, new_person.lastName, new_person.birthDate,
new_person.height, new_person.weight, new_person.BMI, new_person.ID);
if (mysql_query(conn, query))
{
fprintf(stderr, "%s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
free(query);
}
// insert new data into database
if (test == 0)
{
sprintf(query, "INSERT INTO users (id, first_name, last_name, dob, height, weight, BMI) VALUES ('%s', '%s', '%s', '%s', %2.0f, %3.0f, %2.1f)", new_person.ID, new_person.firstName, new_person.lastName,
new_person.birthDate, new_person.height, new_person.weight, new_person.BMI);
if (mysql_query(conn, query))
{
fprintf(stderr, "%s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
free(query);
}
mysql_close(conn);
//show data
// printf("ID: %s\nFirst Name: %s\nLast Name: %s\nBirth Date: %s\nHeight: %2.0f\nWeight: %3.0f\nBMI: %2.1f\n\n", new_person.ID, new_person.firstName, new_person.lastName, new_person.birthDate, new_person.height, new_person.weight, new_person.BMI);
return 0;
}

Thanks to my friend in the above comments leading me to pursue other unknown avenues and thanks to ZetCode # https://zetcode.com/db/mysqlc/
I'm on the right path... though have another issue. I'm not understanding how to use the resulting value - when I use row[0] in a conditional I get an error.
if (mysql_query(conn, exist) != 0)
{
finish_with_error(conn);
}
MYSQL_RES* result = mysql_store_result(conn);
if (result == NULL) {
finish_with_error(conn);
}
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("%s ", row[i] ? row[i] : "NULL");
}
printf("\n");
}
mysql_free_result(result);
mysql_close(conn);
The above is the basic format of what I'm trying to do which provided correct feedback, true and false from the query.

Related

mysql udf c function memory issue

the following test code generates incorrect output when run on a query that returns more than one record
my_bool helloworld_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
strcpy(message, "helloworld() requires one string argument");
return 1;
}
return 0;
}
char *helloworld(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error) {
char *str = args->args[0];
size_t len = strlen(str);
char *ptr = malloc(len + 1);
if (ptr == NULL) {
strcpy(error, "helloworld: failed to allocate memory");
return NULL;
}
for (int i = 0; i < len; i++) {
ptr[i] = str[i];
}
ptr[len] = '\0';
*length = len;
return ptr;
}
void helloworld_deinit(UDF_INIT *initid) {
free(initid->ptr);
}
MariaDB [test]> select helloworld(name) from users;
+------------------+
| helloworld(name) |
+------------------+
| john |
| paul |
| george |
| ringoe |
+------------------+
4 rows in set (0.000 sec)
why ringoe instead of ringo?
I tried different ways to clean up the memory, but the result doesn't change
How do I fix it?
Thanks in advance

How to read data from a text file and put it in a mysql database in c

I have written a c program that I hoped would read data from a text file and put it in a database.
The problem is that the code doesn't execute all iterations of a while loop in the main function as I hoped it would
#Explanation of the algorithm#
The program opens the file that contains the records and reads the whole file into a buffer. Then it chops the string
into records seperated by \n. It then gets each record and composes an sql insert statement then writes the record to the database
Here is the code:
#include <stdio.h>
#include <string.h>
#include <mysql.h>
#define MAX_LEN 1000
/*
#Explanation of the algorithm#
The program opens the file that contains the recored and reads the whole file into a buffer. Then it chops the string
into records. it then gets each record and composes an sql insert statement then writes the record to the database
*/
// function to change the date format to the correct database format
const char* date_formater(char date[],char search_for,char new)
{
int i;
for(i = 0; i <= strlen(date); i++)
{
if(date[i] == search_for)
{
date[i] = new;
}
}
return date;
}
// send data to the database
void send_data_to_database(char str[],MYSQL *con)
{
/*Get data to send to the database*/
char data[8][100];
char delimeter[] = "\t";
char *token = strtok(str,delimeter);
int i = 0;
while(token != NULL)
{
strcpy(data[i],token);
token = strtok(NULL,delimeter);
i++;
}
char o_id[] = "0";
strcpy(data[7],o_id);
// generate sql insert statement
char closingbrac[] = ")";
char single_quote[] = "\'";
char comma[] = ",";
char sql[200] = "INSERT INTO patient VALUES(";
for(int j = 0;j<=7;j++)
{
switch(j)
{
case 0:
strcat(sql,data[j]);
strcat(sql,comma);
break;
case 2:
strcat(sql,single_quote);
const char* real_date = date_formater(data[j],'/','-'); // change date to databse required format
strcat(sql,real_date);
strcat(sql,single_quote);
strcat(sql,comma);
break;
case 7:
strcat(sql,data[j]);
strcat(sql,closingbrac);
printf("%s\n",data[j] );
break;
default:
strcat(sql,single_quote);
strcat(sql,data[j]);
strcat(sql,single_quote);
strcat(sql,comma);
}
}
printf("%s\n",sql);
/*Send SQL query*/
if(mysql_query(con,sql))
{
fprintf(stderr, "%s\n",mysql_error(con));
exit(1);
}
}
/*control function*/
int main()
{
MYSQL *conn;
char *server = "localhost";
char *user = "root";
char *password = "MasterY";
char *database = "covid";
conn = mysql_init(NULL);
/*Connect to database*/
if(!mysql_real_connect(conn,server,user,password,database,0,NULL,0))
{
fprintf(stderr, "%s\n",mysql_error(conn));
exit(1);
}
// open the file containing the patient records
FILE *fptr;
fptr = fopen("/home/elijah/Desktop/plan.txt","r");
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
//open the file containing records for reading
char string[MAX_LEN + 1];
// get all the file contents and store them in a string
fscanf(fptr,"%[^$]",string);
printf("Text file contents:\n%s\n",string);
//puts(string);
printf("String: \n%s\n",string);
char delim[] = "\n";
char *ptr = strtok(string,delim);
while(ptr != NULL)
{
// function call to send data to the database
send_data_to_database(ptr,conn);
ptr = strtok(NULL,delim);
}
/*close connection*/
mysql_close(conn);
//closing the file and clearing it
fclose(fptr);
FILE *file;
file = fopen("/home/elijah/Desktop/plan.txt","w");
fclose(file);
printf("Execution\n");
return 0;
}
The compiler executes the main function up to the while loop. And funnily it only executes one iteration and stops after the first iteration.
Yet I hoped it would continue and finish all the different lines in the text file
It executes the send_data_to_database(ptr,conn); completely.
Here is the text file. Every line is a record that has to be inserted into a database
6 Okello Ivan 2020/10/11 False Positive Assymptomatic M John
7 Leku Davis 2020/02/03 Positive Assymptomatic M Malik Berry
8 Okello Ivan 2020/10/11 False Positive Assymptomatic M John
9 Leku Davis 2020/02/03 Positive Assymptomatic M Malik Berr
Here is a copy of the output:
It only inputs one record into the db. Yet I hoped that it would insert all. I don't know what the problem is but I know something isn't right. That's why I am here.
elijah#elijah-HP-255-G6-Notebook-PC:~/Desktop$ ./mysql
Text file contents:
6 Okello Ivan 2020/10/11 False Positive Assymptomatic M John
7 Leku Davis 2020/02/03 Positive Assymptomatic M Malik Berry
8 Okello Ivan 2020/10/11 False Positive Assymptomatic M John
9 Leku Davis 2020/02/03 Positive Assymptomatic M Malik Berry
String:
6 Okello Ivan 2020/10/11 False Positive Assymptomatic M John
7 Leku Davis 2020/02/03 Positive Assymptomatic M Malik Berry
8 Okello Ivan 2020/10/11 False Positive Assymptomatic M John
9 Leku Davis 2020/02/03 Positive Assymptomatic M Malik Berry
0
INSERT INTO patient VALUES(6,'Okello Ivan ','2020-10-11 ','False Positive ','Assymptomatic ','M ','John',0)
Execution
This is the database table SQL CREATE statement for a MYSQL Database.
CREATE TABLE `patient` (
`idpatient` int(11) NOT NULL AUTO_INCREMENT,
`fullname` varchar(255) NOT NULL,
`date-of-id` date DEFAULT NULL,
`covid-status` varchar(45) DEFAULT NULL,
`nature` varchar(45) DEFAULT NULL,
`gender` varchar(30) DEFAULT NULL,
`officer_name` varchar(45) DEFAULT NULL,
`o-id` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idpatient`,`fullname`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
I compile the source code using this command:
gcc -o mysql -I/usr/include/mysql addtodatabase.c -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -lrt -latomic -lssl -lcrypto -ldl
Because I used #include <mysql.h>
Someone please help me.
#UPDATE
I found out that I could use a csv file to push that data to the database since it's already in tabular format. But I am finding trouble using the LOAD DATA statement.
Here is the updated code
#include <stdio.h>
#include <string.h>
#include <mysql.h>
#define MAX_LEN 1000
/*
#Explanation of the algorithm#
The program opens the file that contains the recored and reads the whole file into a buffer. Then it chops the string
into records. it then gets each record and composes an sql insert statement then writes the record to the database
*/
// function to change the date format to the correct database format
const char* formater(char date[],char search_for,char new)
{
int i;
for(i = 0; i <= strlen(date); i++)
{
if(date[i] == search_for)
{
date[i] = new;
}
}
return date;
}
// send data to the database
void send_data_to_database(MYSQL *con)
{
// SQL QUERY
char sql[] = "LOAD DATA LOCAL INFILE '/home/elijah/Desktop/cron_job/patients.csv' INTO TABLE patient COLUMNS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES (`idpatient`,`fullname`,`date-of-id`,`covid-status`,`nature`,`gender`,`officer_name`,`o-id`)";
/*Send SQL query*/
if(mysql_query(con,sql))
{
fprintf(stderr, "%s\n",mysql_error(con));
exit(1);
}
else
{
printf("Data Sent\n");
}
}
/*control function*/
int main()
{
MYSQL *conn;
char *server = "localhost";
char *user = "root";
char *password = "MasterY";
char *database = "covid";
conn = mysql_init(NULL);
/*Connect to database*/
if(!mysql_real_connect(conn,server,user,password,database,0,NULL,0))
{
fprintf(stderr, "%s\n",mysql_error(conn));
exit(1);
}
// open the file containing the patient records
FILE *fptr;
fptr = fopen("/home/elijah/Desktop/cron_job/patients.txt","r");
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
//open the file containing records for reading
char string[MAX_LEN + 1];
// get all the file contents and store them in a string
fscanf(fptr,"%[^$]",string);
printf("Text file contents:\n%s\n",string);
//puts(string);
printf("String: \n%s\n",string);
// put the data into csv file format and write it
const char *formated_csv_string = formater(string,'\t',',');
char csv_string[] = "idpatient,fullname,date-of-id,covid-status,nature,gender,officer_name,o-id\n";
strcat(csv_string,formated_csv_string);
printf("%s\n",csv_string);
FILE *csv_file;
csv_file = fopen("/home/elijah/Desktop/cron_job/patients.csv","w");
if(csv_file == NULL)
{
printf("Crap\n");
}
else
{
printf("Yayyyyy\n");
fprintf(csv_file, "%s",csv_string);
}
send_data_to_database(conn);
/*close connection*/
mysql_close(conn);
//closing the file and clearing it
fclose(fptr);
// FILE *file;
// file = fopen("/home/elijah/Desktop/cron_job/patients.txt","w");
// fclose(file);
printf("Execution\n");
return 0;
}
The LOAD DATA SQL statement does not work. What could be the problem.
Here is the output
elijah#elijah-HP-255-G6-Notebook-PC:~/Desktop$ ./mysql
Text file contents:
1 Okello Ivan 2020/08/13 False Positive Assymptomatic M Mary 0
String:
1 Okello Ivan 2020/08/13 False Positive Assymptomatic M Mary 0
idpatient,fullname,date-of-id,covid-status,nature,gender,officer_name,o-id
1,Okello Ivan ,2020/08/13 ,False Positive ,Assymptomatic ,M ,Mary,0
Yayyyyy
Data Sent
Execution

mysql, is possible to get statistics about cpu usage and memory, after query or insert command?

On mysql I usually see time of query
select * from rooms;
+---------+---------------+----------+
| number | room_name | identify |
+---------+---------------+----------+
| 1 | myroom | 1 |
| 2 | studio 1 | 4 |
| 3 | Dancefloor | 7 |
+---------+---------------+----------+
3 rows in set (0,00 sec)
Is also possible to get cpu usage and memory from the mysql server?
Yes. It's nothing more than the elapsed time. You can replicate it by storing the start time and subtracting it from the time when the query ends. Like this pseudo-code.
start = Time.now
do_the_query
end = Time.now
elapsed_time = end - start
Digging into the mysql source code, this is nothing more than the elapsed clock time.
Here's the relevant code in client/mysql.cc.
static ulong start_timer(void) {
#if defined(_WIN32)
return clock();
#else
struct tms tms_tmp;
return times(&tms_tmp);
#endif
}
static void end_timer(ulong start_time, char *buff) {
nice_time((double)(start_timer() - start_time) / CLOCKS_PER_SEC, buff, true);
}
static void mysql_end_timer(ulong start_time, char *buff) {
buff[0] = ' ';
buff[1] = '(';
end_timer(start_time, buff + 2);
my_stpcpy(strend(buff), ")");
}
static int com_go(String *buffer, char *line MY_ATTRIBUTE((unused))) {
...
char time_buff[52 + 3 + 1]; /* time max + space&parens + NUL */
...
timer = start_timer();
executing_query = true;
error = mysql_real_query_for_lazy(buffer->ptr(), buffer->length());
...
if (verbose >= 3 || !opt_silent)
mysql_end_timer(timer, time_buff);
else
time_buff[0] = '\0';
If you don't read C...
timer = start_timer(); gets the current time from times.
mysql_real_query_for_lazy runs the query.
mysql_end_timer(timer, time_buff) subtracts the current time from the start time and displays it.

C API Support for calling mysql stored procedure

I'm in the phase of developing a C project which interacts with mysql. So i planned to use mysql stored procedure and found a sample program in this link
I just changed the program according to the requirements of my project. Here is the table structure
id | int(10) unsigned | NO | PRI | NULL | auto_increment |
username | varchar(64) | NO | MUL | NULL | |
password | varchar(25) | NO | | NULL | |
And here is my program.
int main()
{
MYSQL_RES *result;
MYSQL *mysql=mysql_init(NULL);
/* connect to server with the CLIENT_MULTI_STATEMENTS option */
if (mysql_real_connect (mysql, "localhost", "root", "root123","DONT_USE", 0, NULL , CLIENT_MULTI_STATEMENTS) == NULL)
{
printf("mysql_real_connect() failed\n");
mysql_close(mysql);
}
MYSQL_STMT *stmt;
MYSQL_BIND ps_params[1]; /* input parameter buffers */
long int int_data[3]; /* input/output values */
my_bool is_null[3]; /* output value nullability */
int status;
char own_buf[25],input_buf[64];
memset(own_buf, 0, 25);
memset(input_buf, 0, 64);
/* set up stored procedure */
status = mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
test_error(mysql, status);
status = mysql_query(mysql,
"CREATE PROCEDURE p1("
" IN p_in VARCHAR(64)) "
"BEGIN "
" SELECT password from data where username=p_in; "
"END");
test_error(mysql, status);
/* initialize and prepare CALL statement with parameter placeholders */
stmt = mysql_stmt_init(mysql);
if (!stmt)
{
printf("Could not initialize statement\n");
}
status = mysql_stmt_prepare(stmt, "CALL p1(?)", 10);
test_stmt_error(stmt, status);
/* initialize parameters: p_in, p_out, p_inout (all INT) */
memset(ps_params, 0, sizeof (ps_params));
ps_params[0].buffer_type = MYSQL_TYPE_STRING;
ps_params[0].buffer = (void *) &input_buf;
ps_params[0].buffer_length = sizeof(input_buf);
ps_params[0].is_null = 0;
/* bind parameters */
status = mysql_stmt_bind_param(stmt, ps_params);
test_stmt_error(stmt, status);
/* assign values to parameters and execute statement */
int_data[0]= 2; /* p_in */
int_data[1]= 20; /* p_out */
strcpy(input_buf,"'6666600222'");
int_data[0] = strlen(input_buf);
input_buf[int_data[0]] = '\0';
ps_params[0].length = &int_data[0];
status = mysql_stmt_execute(stmt);
test_stmt_error(stmt, status);
/* process results until there are no more */
do {
int i;
int num_fields; /* number of columns in result */
MYSQL_FIELD *fields; /* for result set metadata */
MYSQL_BIND *rs_bind; /* for output buffers */
/* the column count is > 0 if there is a result set */
/* 0 if the result is only the final status packet */
num_fields = mysql_stmt_field_count(stmt);
if (num_fields > 0)
{
/* there is a result set to fetch */
printf("Number of columns in result: %d\n", (int) num_fields);
/* what kind of result set is this? */
printf("Data: ");
if(mysql->server_status & SERVER_PS_OUT_PARAMS)
printf("this result set contains OUT/INOUT parameters\n");
else
printf("this result set is produced by the procedure\n");
MYSQL_RES *rs_metadata = mysql_stmt_result_metadata(stmt);
test_stmt_error(stmt, rs_metadata == NULL);
fields = mysql_fetch_fields(rs_metadata);
rs_bind = (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
if (!rs_bind)
{
printf("Cannot allocate output buffers\n");
}
memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);
/* set up and bind result set output buffers */
for (i = 0; i < num_fields; ++i)
{
rs_bind[i].buffer_type = fields[i].type;
rs_bind[i].is_null = &is_null[i];
switch (fields[i].type)
{
case MYSQL_TYPE_LONG:
rs_bind[i].buffer = (char *) &(int_data[i]);
rs_bind[i].buffer_length = sizeof (int_data);
break;
case MYSQL_TYPE_VAR_STRING:
rs_bind[i].buffer = (char *) own_buf;
rs_bind[i].buffer_length = sizeof(own_buf);
rs_bind[i].length = &int_data[1];
break;
default:
fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
}
}
status = mysql_stmt_bind_result(stmt, rs_bind);
test_stmt_error(stmt, status);
/* fetch and display result set rows */
while (1)
{
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA)
break;
for (i = 0; i < num_fields; ++i)
{
switch (rs_bind[i].buffer_type)
{
case MYSQL_TYPE_LONG:
if (*rs_bind[i].is_null)
printf(" val[%d] = NULL;", i);
else
printf(" val[%d] = %ld;",
i, (long) *((int *) rs_bind[i].buffer));
break;
case MYSQL_TYPE_VAR_STRING:
printf(" val[%d] = %s;",i,(char*)rs_bind[i].buffer);
break;
default:
printf(" unexpected type (%d)\n",
rs_bind[i].buffer_type);
}
}
printf("\n");
}
mysql_free_result(rs_metadata); /* free metadata */
free(rs_bind); /* free output buffers */
}
else
{
/* no columns = final status packet */
printf("End of procedure output\n");
}
/* more results? -1 = no, >0 = error, 0 = yes (keep looking) */
status = mysql_stmt_next_result(stmt);
if (status > 0)
test_stmt_error(stmt, status);
} while (status == 0);
mysql_stmt_close(stmt);
}
OUTPUT:
Number of columns in result: 1
Data: this result set is produced by the procedure
End of procedure output
Above code works fine in case of integer argument like CREATE PROCEDURE p1(IN p_in INT) but not for varchar arguments.
link as mentioned in the link for varchar input parameter type is MYSQL_TYPE_STRING and output parameter type is MYSQL_TYPE_VAR_STRING
Problem:
Getting empty result.
As far my analysis, status = mysql_stmt_fetch(stmt); function returns 100(MYSQL_NO_DATA) though the entry present in the table.
NOTE: I tried calling the procedure manually into mysql like call p1('6666600222'); which results
mysql> call p1('6666600222');
+----------+
| password |
+----------+
| 1234 |
+----------+
1 row in set (0.00 sec)
Anyone help me to short out this?
In order to set a varchar param, ps_params should take pointer to char not pointer to pointer to char.
Try change:
ps_params[0].buffer = (void *) &input_buf;
to:
ps_params[0].buffer = (void *)&(input_buf[0]); // or just (void *)input_buf
And after set string value to input_buf set ps_params[0].buffer_length as below:
ps_params[0].buffer_length = strlen(input_buf);
Hope this helps

How to separate result values in different rows using Mysql query

I created this table (results) in my sql database (test)
CREATE DATABASE `test`;
USE `test`;
CREATE TABLE `results` (
`number` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`id_machine` int(10) unsigned NOT NULL,
`value` float NOT NULL,
`datetime` datetime NOT NULL,
PRIMARY KEY (`number`),
UNIQUE KEY `indice_UNIQUE` (`number`)
) ENGINE=InnoDB AUTO_INCREMENT=100;
My external device gives me these results:
+DATA: 43 BYTES FROM 0000:0000 (045)
Machine_8: (T=22.22, HR=42.56, Dw=8.95, VCC=3.64V)
and with the usage of strtok I get some values of these results to save them in the database:
Results: 8, 22.22, 42.56, 8.95, 3.64
I would like to save my data in my table in this way:
101, 8, 22.22, 2013-06-05 14:03:00
102, 8, 42.56, 2013-06-05 14:03:00
103, 8, 8.95, 2013-06-05 14:03:00
104, 8, 3.64, 2013-06-05 14:03:00
This is my code in my function until now
int learn_port2(int fd)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_RES *res1;
MYSQL_ROW row;
char *server = "127.0.0.1";
char *user = "root";
char *password = "***"; // got tot keep my data secret
char *database = "test";
conn = mysql_init(NULL);
if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))
{
fprintf(stderr, "%s\n", mysql_error(conn));
return -1;
//finish_with_error(conn);
}
int n, i;
char buff[300];
memset(buff, 0, sizeof(buff));
for (int x = 0; x<1; x++)
//for (;;)
{
char id_machine[35] = "";
char temp[35] = "";
char hum[35] = "";
char dw[35] = "";
char vol[45] = "";
char* ptr;
int i,nodo,nodo1;
float temp, hum, dw, vcc;
n=read(fd,buff,sizeof(buff));
sleep(1);
printf("%s", buff);
printf("\n");
if (buff[37] == 'N' || buff[38] == 'N' || buff[39] == 'N' || buff[40] == 'N' )
{
ptr = strtok(buff, "Machine_,=T:HR:DW:Vcc()");
i = 0;
while (ptr != NULL)
{
if (i == 9)
strcat(id_machine, ptr); // copies Nodo
if (i == 10)
strcat(temp, ptr); // copies T
if (i == 11)
strcat(hum, ptr); // copies HR
if (i == 13)
strcat(dw, ptr); // copies DW
if (i == 15)
strcat(vol, ptr); // copies Vcc
ptr = strtok(NULL, "Machine_,=T:HR:DW:Vcc()");
i++;
}
printf("Results: %s, %s, %s, %s, %s\n", id_machine, temp, hum, dw, vol);
}
char query[]="INSERT INTO results(`id_machine`,`value`,`valor`) VALUES(id_machine,'14',value)";
if(mysql_query(conn, query))
{
fprintf(stderr, "%s\n", mysql_error(conn));
return -1;
}
res = mysql_use_result(conn);
}
}
How can I modify the char query[] to have the results which I want? Or if there are some examples like this.
To make a parameterized query you could use something like the following...
The example uses vsnprintf() to take a printf like format string and a variable number of arguments after it to print the query into a temporary buffer and then pass the buffer to the MYSQL query. In this way you can get a paramaterized query...
vsnprintf() accepts a variable parameter list, va_list and also is buffer-overflow safe.
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#define BUFSTRLEN 255
/* Returns -1 if the internal buffer was not large enough to hold the formatted
* string, or a format error occurred. If neither condition occurred then the
* result of the MYSQL query is returned... */
int DoMysqlQuery(MYSQL *conn, char const *printfstring, ...)
{
int len;
va_list args;
char buffer[BUFSTRLEN + 1];
memset(buffer, '\0', sizeof(buffer));
va_start(args, printfstring);
len = vsnprintf(buffer, BUFSTRLEN, printfstring, args);
va_end(args);
/* Did the buffer print work ? */
if( len < 0 || len >= BUFSTRLEN + 1 )
return -1;
return mysql_query(conn, buffer);
}
int main(int argc, char const *argv[])
{
int result;
MYSQL mysqlConn = ...;
/* Example stuff to send to the function.... */
char *id_machine= "8";
char *value= "1234";
char *valor= "1";
/* Send the query */
result = DoMysqlQuery(
&mysqlConn,
"INSERT INTO results(`id_machine`,`value`,`valor`) VALUES(%s,'%s',%s);",
id_machine, value, valor);
if( result )
{
/* handle error etc... *.
}
}
In this example, the query string that will be sent to mysql_query() is:
INSERT INTO results(id_machine,value,valor) VALUES(8,'1234',1);
Hope this helps :)