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
Related
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.
i met a issue during my development on mysql and linux C.
as the procedure use temporary params, so I think it will not affect following sql query. but my test is failed and report errno:2014.
the procedure I used is :
delimiter //
drop procedure if exists pbx_r_eid_svcid;
CREATE PROCEDURE `pbx_r_eid_svcid`(IN input_eid varchar(16))
begin
declare exe_result int default -1;
declare out_svcip varchar(64) default "";
declare out_svcport varchar(64) default "";
select exe_result,out_svcip,out_svcport;
end;//
delimiter;
C code:
#include <mysql/mysql.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
MYSQL *mysql;
int timeout=atoi(argv[1]);
char escape[64] = "";
char orig[64] = "";
char buf[128] = "";
int rc = 0;
MYSQL_RES *res;
mysql = mysql_init(NULL);
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, &timeout);
mysql_options(mysql, MYSQL_OPT_WRITE_TIMEOUT, &timeout);
mysql_real_connect(mysql, "127.0.0.1", "root", "123456", "center_distribute", 3306,"/var/run/mysqld/mysqld.sock", CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS);
snprintf(buf,128, "call pbx_r_eid_svcid('00000002')", "11");
if (mysql_real_query(mysql,buf,strlen(buf)))
{
int err_no = mysql_errno(mysql);
fprintf(stderr, "Failed to insert row, Error: %d %s\n", err_no,
mysql_error(mysql));
}
res = mysql_store_result(mysql);
if(0 == mysql_affected_rows(mysql) || res == NULL)
{
rc = 6;
goto end;
}
mysql_free_result(res);
snprintf(buf,128,"select * from enterprise_info;");
/******************************/
/*wrong query return out of sync*/
if (mysql_real_query(mysql,buf,strlen(buf)))
{
int err_no = mysql_errno(mysql);
fprintf(stderr, "Failed to insert row, Error: %d %s\n", err_no,
mysql_error(mysql));
}
res = mysql_store_result(mysql);
if(0 == mysql_affected_rows(mysql) || res == NULL)
{
rc = 7;
goto end;
}
mysql_free_result(res);
end:
printf("%d\n",rc);
mysql_close(mysql);
return 0;
}
second mysql select will repsonse out of sync error
test reult:
./mt 5
Failed to insert row, Error: 2014 Commands out of sync; you can't run this
command now
7
any comment should be helpful.
Thanks.
I have a temperature sensor hooked up to a Raspberry Pi, I am able to read and printf the temperature. What I am trying to do next is to get the values from the sensor and have them get logged into a MySQL database.
Everything works, except, I can not figure out how to format the MySQL insert Query to use the f variable and the h variable that is generated by the read_dht_data() function and pass it to the MIA_temp_insert(float f, float h).
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <wiringPi.h>
#include <stdint.h>
#define MAX_TIMINGS 85
#define DHT_PIN 3 /* GPIO-22 */
int data[5] = { 0, 0, 0, 0, 0 };
float temp_f;
static char *host = "XXX.XXX.XXX.XXX";
static char *user = "XXX";
static char *password = "XXX";
static char *dbname = "XXX";
unsigned int port = 3306;
static char *unix_socket = NULL;
unsigned int flag = 0;
static MYSQL *conn; //Needed to be static so all of the functions can draw from it
void MIA_mysql_connection()
{
// Connecting to the Database
conn = mysql_init(NULL);
if (!(mysql_real_connect(conn, host, user, password, dbname, port, unix_socket, flag)))
{
fprintf(stderr, "\n Error: %s [%d] \n", mysql_error(conn),mysql_errno(conn));
exit (1);
}
//Connected
printf ("We Are Connected \n");
}
void MIA_mysql_close()
{
//Closing Connection
mysql_close(conn);
}
void MIA_temp_insert(float f, float h)
{
//Inserting into MySQL Table
if(mysql_query(conn, "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')") !=0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
} else {
printf("Rows were insert \n");
}
}
void read_dht_data()
{
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0, i;
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
/* pull pin down for 18 milliseconds */
pinMode( DHT_PIN, OUTPUT );
digitalWrite( DHT_PIN, LOW );
delay( 18 );
/* prepare to read the pin */
pinMode( DHT_PIN, INPUT );
/* detect change and read data */
for ( i = 0; i < MAX_TIMINGS; i++ )
{
counter = 0;
while ( digitalRead( DHT_PIN ) == laststate )
{
counter++;
delayMicroseconds( 1 );
if ( counter == 255 )
{
break;
}
}
laststate = digitalRead( DHT_PIN );
if ( counter == 255 )
break;
/* ignore first 3 transitions */
if ( (i >= 4) && (i % 2 == 0) )
{
/* shove each bit into the storage bytes */
data[j / 8] <<= 1;
if ( counter > 16 )
data[j / 8] |= 1;
j++;
}
}
/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
if ( (j >= 40) &&
(data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
{
float h = (float)((data[0] << 8) + data[1]) / 10;
if ( h > 100 )
{
h = data[0]; // for DHT11
}
float c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
if ( c > 125 )
{
c = data[2]; // for DHT11
}
if ( data[2] & 0x80 )
{
c = -c;
}
float f = c * 1.8f + 32;
//printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
printf ("Temp of the room is : %.1f \n",f);
//Insert Data into MIA Temperature Table
MIA_temp_insert(10.0,11.1);
}else {
//printf( "Data not good, skip\n" );
}
}
int main ()
{
printf( "Raspberry Pi DHT11/DHT22 temperature/humidity test\n" );
if ( wiringPiSetup() == -1 )
exit( 1 );
while ( 1 )
{
MIA_mysql_connection();
read_dht_data();
delay (1000);
MIA_mysql_close();
printf("End of program \n");
}
return(0);
}
You cannot use printf()-style format specifiers in mysql_query() directly as you have above. Instead, you can use sprintf() or snprintf() to write the format string -- with the formatted numbers instead of format specifiers -- into a buffer... then pass that as your query string.
So in MIA_temp_insert(), instead of the following:
if(mysql_query(conn, "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')") !=0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
/* ...etc... */
...you could try this:
/* Your original query string, with the %f specifiers */
const char *formatstring = "INSERT INTO `temperature` (`id`, `Date`,`Time`, `Temperature`, `Humidity`) VALUES (NULL, CURRENT_DATE(), CURRENT_TIME(), '%f' , '%f')";
/* snprintf() the query into a buffer, to fill in the numbers */
char buf[256]; // should be large enough for the query with the numbers filled in
if (snprintf(buf, sizeof(buf), formatstring, f, h) >= sizeof(buf))
{
exit(-1); // if snprintf() returned sizeof(buf) or more, buf was too short
}
/* call mysql_query() with the formatted query from the buffer */
if (mysql_query(conn, buf) != 0)
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit (-1);
/* ...etc... */
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 :)
For the purpose of the exercise, I have to implement the exponential function with the most basic arithmetic operations. I came up with this, where x is the base and y the exponent:
function expAetB() {
product=1;
for (i=0; i<y; i++)
{
product=product*x;
}
return product;
};
However, there are more basic operations than product=product*x;. I should somehow be able to insert instead another for loop which multiply and pass the result, but I can't find a way to do it without falling into an infinite loop.
In the same way that exponentiation is repeated multiplication, so multiplication is simply repeated addition.
Simply create another function mulAetB which does that for you, and watch out for things like negative inputs.
You could go even one more level and define adding in terms of increment and decrement, but that may be overkill.
See, for example, the following program which uses the overkill method of addition:
#include <stdio.h>
static unsigned int add (unsigned int a, unsigned int b) {
unsigned int result = a;
while (b-- != 0) result++;
return result;
}
static unsigned int mul (unsigned int a, unsigned int b) {
unsigned int result = 0;
while (b-- != 0) result = add (result, a);
return result;
}
static unsigned int pwr (unsigned int a, unsigned int b) {
unsigned int result = 1;
while (b-- != 0) result = mul (result, a);
return result;
}
int main (void) {
int test[] = {0,5, 1,9, 2,4, 3,5, 7,2, -1}, *ip = test;
while (*ip != -1) {
printf ("%d + %d = %3d\n" , *ip, *(ip+1), add (*ip, *(ip+1)));
printf ("%d x %d = %3d\n" , *ip, *(ip+1), mul (*ip, *(ip+1)));
printf ("%d ^ %d = %3d\n\n", *ip, *(ip+1), pwr (*ip, *(ip+1)));
ip += 2;
}
return 0;
}
The output of this program shows that the calculations are correct:
0 + 5 = 5
0 x 5 = 0
0 ^ 5 = 0
1 + 9 = 10
1 x 9 = 9
1 ^ 9 = 1
2 + 4 = 6
2 x 4 = 8
2 ^ 4 = 16
3 + 5 = 8
3 x 5 = 15
3 ^ 5 = 243
7 + 2 = 9
7 x 2 = 14
7 ^ 2 = 49
If you really must have it in a single function, it's a simple matter of refactoring the function call to be inline:
static unsigned int pwr (unsigned int a, unsigned int b) {
unsigned int xres, xa, result = 1;
// Catch common cases, simplifies rest of function (a>1, b>0)
if (b == 0) return 1;
if (a == 0) return 0;
if (a == 1) return 1;
// Do power as repeated multiplication.
result = a;
while (--b != 0) {
// Do multiplication as repeated addition.
xres = result;
xa = a;
while (--xa != 0)
result = result + xres;
}
return result;
}