Not able to detect integer values in where clause - mysql

I am trying to read column values into my array using mysql queries in C.
for(i=1;i<=15;i++)
{
if (mysql_query(conn, "select numberofskills from latest.skills where id = $i")) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res = mysql_use_result(conn);
while ((row = mysql_fetch_row(res)) != NULL){
j=0;
arr[j].n =atoi(row[0]);
printf("%d\n", arr[j].n);
j++;
}
I have an error saying "Unknown column '$i' in 'where clause'.
I tried all of these but nothing seems to work.
"select numberofskills from latest.skills where id = $i"
"select numberofskills from latest.skills where id = '$i'"
"select numberofskills from latest.skills where id = i"

$i will not replace the value of i. Instead you should format the string first with value of i replaced in it and then use the string in the mysql query.
In header file or in the beginning of the program, define the below macro:
#define MYSQL_QUERY_LENGTH 100
Inside your function where you are performing query, define the below variable:
char string[MYSQL_QUERY_LENGTH] = {};
Inside the for loop, format the string first:
snprintf(string, MYSQL_QUERY_LENGTH, "select numberofskills from latest.skills where id = %d", i);
Then, use the string in the query as below:
if (mysql_query(conn, string))

First you need to create query string variable with sprintf function where you can properly concatenate your query and variable
here is example
mysql and c -- use variable in query

Related

C mysql prepared statement inserting null character

I'm trying to set up a prepared statement based on some examples I found on the web. I just want to protect against SQL injections in the name= and description=, but the problem is that when the statement runs it inserts null data
char* my_str = "ABCDF";
char *stmt_str = "INSERT INTO notes (name, description) VALUES(?,?)";
MYSQL_STMT *stmt;
MYSQL_BIND ps_params[2];
my_bool is_null;
int status;
while(curr != NULL) {
stmt = mysql_stmt_init(con);
mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str));
memset(ps_params, 0, sizeof(ps_params));
/* set up CHAR parameter */
ps_params[0].buffer_type = MYSQL_TYPE_STRING;
//ps_params[0].buffer = (char *)&my_str;
ps_params[0].buffer = &my_str;
ps_params[0].buffer_length=strlen(my_str);
ps_params[0].is_null = 0;
ps_params[0].length = 0;
ps_params[1].buffer_type = MYSQL_TYPE_STRING;
//ps_params[1].buffer = (char *)&my_str;
ps_params[1].buffer = &my_str;
ps_params[1].buffer_length=strlen(my_str);
ps_params[1].is_null = 0;
ps_params[1].length = 0;
mysql_stmt_bind_param (stmt, ps_params);
mysql_stmt_execute(stmt);
Once it executed I see the following data ( It's a bunch of records in my DB ) after executing it many times
my_str is already a pointer to the string, you shouldn't take its address. You're storing the pointer's value rather than the string value.
ps_params[0].buffer = my_str;

"unknown column in field list" error when passing custom string into MariaDB/MySQL C connector API function

I am trying to make a function which requests the user to enter a new username and password, which then get stored in a MySQL/MariaDB database. I used strcat_s() and strcpy_s() to concatenate strings together to then get passed as a MySQL/MariaDB query in the C API. However, the result is an Unkown column 'foo' in 'field list' error. How can I fix this error? Below is my code.
void NEW_PLAYER(MYSQL *con)
{
const char *NAME = "foo";
const char *PASSWORD = "bar";
char ch = NULL;
unsigned int i = 0;
printf("%s\n", NAME);
printf("%s\n", PASSWORD);
char TEMP[150];
char str1[] = "INSERT INTO PLAYERS VALUES(";
strcpy_s(TEMP, str1);
strcat_s(TEMP, NAME);
strcat_s(TEMP, ", ");
strcat_s(TEMP, PASSWORD);
strcat_s(TEMP, " ,0, 0, 0, 0)");
printf("%s", TEMP);
// inserting null character at end
if (mysql_query(con, TEMP)) {
fprintf(stderr, "%s\n", mysql_error(con));
exit(-1);
}
}
Here are my results from this code
Strings must be quote, so you must quote 'foo' and 'bar' like this:
const char *NAME = "'foo'";
const char *PASSWORD = "'bar'";

retrieving every attribute of every column from every row of a table mysql java

So far I know that it's possible to select the nth row from a table using the following code SELECT * FROM table ORDER BY column_name LIMIT n-1,1 ; In the following code I am trying to retrieve every attribute of every column from every row of a table named responsable which has the following columns :id,name,surname,mail,password. id is an integer while the other columns' type is string
java.sql.Connection connection = null;
int rowCount;
try {connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/database_name","root","");
Statement stmt = null;
ResultSet result = null;
ResultSet rs = null;
rs = stmt.executeQuery("SELECT COUNT(*) FROM responsable");
rowCount = rs.getInt(1);
if(rowCount!=0)
{
for(int i=0;i<rowCount;i++)
{result= stmt.executeQuery("SELECT * FROM responsable ORDER BY id LIMIT"+i+",1");
System.out.put(result.getInt(1));
System.out.put(result.getString(2));
System.out.put(result.getString(3));
System.out.put(result.getString(4));
System.out.put(result.getString(5));}
}
}catch (Exception ex) {
out.println("Unable to connect to database");
}
I am trying to execute this code but I am getting no result.
Any help would be appreciated.
Your stmt variable is null. You need to create the statement first.
Statement stmt = connection.createStatement();
Also, you need to call next() to retrieve the next row from your resultset.
E.g.
if (rs.next()) {
rowCount = rs.getInt(1);
}
....
if (result.next()) {
System.out.put(result.getInt(1));
System.out.put(result.getString(2));
System.out.put(result.getString(3));
System.out.put(result.getString(4));
System.out.put(result.getString(5));
}

Executing multiple COUNT queries in Java

I have a MySQL database (ver. 5.2 CE) and I have a table which I want to filter into a another table based on the WHERE conditions given by the user (this comes from an array list). I want to perform count query on this new table for a split chosen by the user. For example, COUNT(*) from TableName WHERE [userConditions like gender=male and gender=female, etc]. The user can give more than one WHERE conditions but the COUNT query will only take one condition at a time. Hence, I made my method (which performs this query) an array to return multiple queries based on the number of conditions chosen by the user and then execute each query in a for loop. However, this seems to give me compilation errors in 2 ways: i) the way I return a built string in a String[] method and ii) the way I execute the COUNT query. The code for these problems:
private String countQuery;
public SetupSubsamplePopulation(UserSelectedSplit split) {
this.split = split;
// connect to the database
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?zeroDateTimeBehavior=convertToNull","root", "sharadha_1992");
String buildSelectQuery = buildSelectQueryForCode();
String getRowsFromTable = getNumberOfRows();
stmt = connection.createStatement();
rows = stmt.executeUpdate(buildSelectQuery);
ResultSet rs = stmt.executeQuery(getRowsFromTable);
for (int i=0; i<getCountOfWhereCondition().length; i++){
//where I get the executeQuery error
ResultSet rs1= stmt.execute(getCountOfWhereCondition());
while (rs1.next()){
rowsCount= rs.getRow();
rows_count++;
}
}
while (rs.next()) {
rows = rs.getRow();
rows_inserted++;
}
System.out.println(rows_inserted);
System.out.println(rows_count);
} catch (Exception e) {
e.printStackTrace();
}
}
The method which returns the array of COUNT queries:
public String[] getCountOfWhereCondition() {
countQuery="SELECT COUNT (*) FROM (SELECT * from mygrist_samples.subsample_population WHERE ";
for (int i = 0; i < split.getSplitConditions().size(); i++) {
String getCorrespondingCodeFromDatabase = split.getSplitConditions().get(i).getCode();
getCorrespondingCodeFromDatabase = getCorrespondingCodeFromDatabase.replaceAll("-", "_");
Enumerations enum1 = new Enumerations();
String getCorrespondingRelationshipOperator = enum1.getOperator(split.getSplitConditions().get(i).getRelationship());
countQuery+=getCorrespondingCodeFromDatabase + " " + getCorrespondingRelationshipOperator + " '" + split.getSplitConditions().get(i).getAnswer() + "'";
}
countQuery+=")";
System.out.println(countQuery);
//error which doesn't allow me to return a string
return countQuery;
}
Can someone please tell me how to implement this sensibly? Thank you very much.
I think you want conditional aggregation rather than a where:
select count(*)
from mygrist_samples.subsample_population
WHERE XXX
Is the same as:
select sum(case when XXX then 1 else 0 end) as cnt1
from mygrist_samples.subsample_population
Now you can add multiple conditions on one call:
select sum(case when XXX then 1 else 0 end) as cnt1,
sum(case when yyy then 1 else 0 end) as cnt1
from mygrist_samples.subsample_population

mysql prepared statement : Update query

I am trying to execute a C program, using mysql C API, connecting to mysql with an update query and I am not getting any compilation or linking errors , but rows are not getting updated in the db table.
When I run this code I am getting empty values updated in emp. status field
#define STRING_SIZE 256
char* eStatus,myeStatus;
int myempid,empid;
int i;
for(i = 0; i < 5 ; i++){
const char* sqlQuery = "update employee_info set estatus = ? where empID = ?";
if (mysql_stmt_prepare(stmt, sqlQuery, strlen(sqlQuery))) {
fprintf(stderr, " mysql_stmt_prepare(), update failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
return -1;
}
memset(param, 0, sizeof(param)); /* zero the structures */
if (info.state == 2)
eStatus = "present";
else
eStatus = "absent";
empid = i;
// Init param structure
// Select
param[0].buffer_type = MYSQL_TYPE_STRING;
param[0].buffer = (void *) &eStatus;
param[0].buffer_length = STRING_SIZE;
param[0].is_null = 0;
param[0].length = &str_length;
param[1].buffer_type = MYSQL_TYPE_SHORT;
param[1].buffer = (void *) &myempID;
param[1].buffer_length = STRING_SIZE;
param[1].is_null = 0;
param[1].length = 0;
myeStatus = eStatus;
myempid = empid;
if (mysql_stmt_bind_param(stmt, param) != 0) {
fprintf(stderr, " mysql_stmt_bind_param() failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
return -1;
}
/* Execute the statement */
if (mysql_stmt_execute(stmt)) {
fprintf(stderr, " mysql_stmt_execute(), failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
return -1;
}
} // end of for loop
Table schema in mysql
empid INT(11)
estatus varchar(10)
I am not able to figure out why status is not getting updated in mysql table. Is it a mismatch of datatypes, or values are not binded properly to sqlquery?
Any clue? Thanks.
You can find here : Writing into mysql database from a single board computer using c a complete example on how to use MYSQL C API to perform queries, if you still have some trouble, please post the whole code.
Why are you trying to use "where empID = ?". If you want it to run for every employee simply omit the where clause. If it is for a specific employee, then his id should be there.
There might be more issues, but this was the first one i found.
You might verify by trying to execute the same query on mysql command line prompt.
Edit: I also don't see any database connection being established and any info related to that. Some thing like
MYSQL *conn = mysql_init(NULL);
*conn = mysql_real_connect(*conn, DB_HOST, DB_USER, DB_PASS, DB_NAME, 0, NULL, flags);
if (*conn != NULL)
{
printf("Connection Successfull\n");
status = 0;
}