Why does mysql_query() print an error? - mysql

I am just starting with C and the MySQL C API. I am using mysql_query() to create a table. According to the manual, the function usage is int mysql_query(MYSQL *mysql, const char *stmt_str), and the function returns 0 if successful or non-zero on error. However, whether I use if (mysql_query()) or if ! (mysql_query()), the program always prints to stdout, "Error 0:". Also, in either case, the program does create the database and table.
#include <my_global.h>
#include <mysql.h>
int main (int argc, char **argv)
{
MYSQL *connection;
const char DATABASE[] = "test";
const char HOSTNAME[] = "localhost";
const char USERNAME[] = "root";
const char PASSWORD[] = "123456";
connection = mysql_init(NULL);
if (connection == NULL)
{
printf("Error %u: %s\n", mysql_errno(connection), mysql_error(connection));
exit(1);
}
if (mysql_real_connect(connection, HOSTNAME, USERNAME, PASSWORD, NULL, 0, NULL, 0) == NULL)
{
printf("Error %u: %s\n", mysql_errno(connection), mysql_error(connection));
exit(1);
}
if (mysql_query(connection, "DROP DATABASE IF EXISTS test"))
{
printf("Error %u: %s\n", mysql_errno(connection), mysql_error(connection));
exit(1);
}
if (mysql_query(connection, "CREATE DATABASE test"))
{
printf("Error %u: %s\n", mysql_errno(connection), mysql_error(connection));
exit(1);
}
if (mysql_select_db(connection, DATABASE))
{
printf("Error %u: %s\n", mysql_errno(connection), mysql_error(connection));
exit(1);
}
/* The problem that I do not understand is happening in the statement below.
* It seems that a successful query returns zero, so I should not see "Error 0:"
*/
if (mysql_query(connection, "CREATE TABLE jobs (id int(11) NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL, PRIMARY KEY (id), UNIQUE KEY name_index (name)) ENGINE=InnoDB DEFAULT CHARSET=utf8"));
{
printf("Error %u: %s\n", mysql_errno(connection), mysql_error(connection));
exit(1);
}
mysql_close(connection);
}

You simply have put a semicolon ; at the end of the if statement so the code between the curly braces gets always executed!!!
Take away the ; and everything will work as expected

This is not completely clear from the man page, but my guess would be that the return code of the function is the error code. So you'd have to capture that return value in a variable and then print the value of that variable in case of an error.

Related

Get the resultset field type in mySQL C interface

ALL,
I skimmed thru the mySQL C API documentation, but couldn't find it.
Then I googled and I got this which is for C++ and not C.
So, the question is - is there a C equivalent for the link above? Or some other means to retrieve the field type of the arbitrary query?
TIA!!
To get the field type, you can access the field information after fetching a row by using mysql_fetch_field() as suggested by Barmar in his comment.
The structure MYSQL_FIELD has a member named type which is an enum. The enum enum_field_types can be found in field_types.h.
A complete, self-contained example program might look like this:
#include <mysql.h>
#include <stdio.h>
void error(MYSQL *con, const char *msg, const char *error) {
fprintf(stderr, "%s: %s\n", msg, error);
if (con) {
mysql_close(con);
}
exit(1);
}
char *type_info(enum enum_field_types type) {
switch (type) {
case MYSQL_TYPE_VARCHAR:
return "VARCHAR";
case MYSQL_TYPE_NEWDECIMAL:
return "NEWDECIMAL";
case MYSQL_TYPE_LONG:
return "LONG";
case MYSQL_TYPE_VAR_STRING:
return "VAR_STRING";
//...several cases omitted see field_types.h
default:
return "UNKNOWN";
}
}
int main(void) {
MYSQL *con = mysql_init(NULL);
if (con == NULL) {
error(con, "initialization failed", mysql_error(con));
}
if (!mysql_real_connect(con, "localhost", "root", "admin123", "db", 3306, NULL, 0)) {
error(con, "couldn't connect", mysql_error(con));
}
if (mysql_query(con, "select * from animals;")) {
error(con, "query failed", mysql_error(con));
}
MYSQL_RES *result = mysql_use_result(con);
if (result == NULL) {
printf("empty result\n");
}
if (mysql_fetch_row(result)) {
MYSQL_FIELD *field;
while ((field = mysql_fetch_field(result))) {
printf("|%s ", field->name);
printf("%s| ", type_info(field->type));
}
printf("\n");
}
printf("\n");
mysql_close(con);
return 0;
}
Test
For the simple test table Animals, the output of name and type would look like this:
|id LONG| |kind VAR_STRING| |name VAR_STRING| |weight NEWDECIMAL|

MySQL C API parameterized query fetch result

I've been like 3 hours on this and I can't make this work.
I read MySQL C API documentation like 10 times about mysql_stmt functions.
What I need is like this: mysql_stmt_fetch()
The thing is I need a parametrized query because there is 1 user input.
Code is as follows:
char* regSol(char* token,MYSQL *conn){
char* regnr;
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
unsigned long str_length;
/*
* Validation
*/
stmt = mysql_stmt_init(conn);
char *sql="SELECT REGNR,Token FROM registed WHERE Token=?";
if(mysql_stmt_prepare(stmt,sql,strlen(sql))){
fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(1);
}
memset(bind, 0, sizeof(bind)); //clears the structure.
bind[0].buffer= 0;
bind[0].buffer_length= 0;
bind[0].length= &str_length;
if(mysql_stmt_bind_result(stmt,bind))
{
fprintf(stderr, " mysql_stmt_bind_result(), failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(1);
}
/*
fetch data
*/
unsigned long long nrow=0;
mysql_stmt_fetch(stmt);
if (str_length > 0)
{
char *data= (char*) malloc(str_length);
bind[0].buffer= data;
bind[0].buffer_length= str_length;
mysql_stmt_fetch_column(stmt, bind, 0, 0);
fprintf(stdout,"DEBUG !! - %s - !!\n",data);
}
return NULL;
}
I already tested mysql_stmt_bind_result and other functions.
The first try was preparing, binding and execute. fetch num of rows and it was always 0. No matter what, always 0.
Can anyone tell me the right way to get a result from a parametrized query?
EDIT 1:
new code that seems what will work but something is weird:
char* regSol(char* token,MYSQL *conn){
/*
* Needs to be completed. I have no idea why I can make this work
* Tested a lot of functions and got some SEGVs and 0 rows.
* And results that aren't even in the database
*/
char* regnr;
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
unsigned long str_length;
/*
* Validation
*/
stmt = mysql_stmt_init(conn);
char *sql="SELECT REGNR FROM registed WHERE Token=?";
if(mysql_stmt_prepare(stmt,sql,strlen(sql))){
fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(1);
}
memset(bind, 0, sizeof(bind)); //clears the structure.
bind[0].buffer_type=MYSQL_TYPE_STRING;
bind[0].buffer=(char*)token;
bind[0].buffer_length=strlen(token)+1;
bind[0].length= &str_length;
if(mysql_stmt_bind_param(stmt,bind))
{
fprintf(stderr, " mysql_stmt_bind_param(), failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(1);
}
if(mysql_stmt_execute(stmt)){
fprintf(stderr," mysql_stmt_execute(), failed\n");
fprintf(stderr, "%s\n",mysql_stmt_error(stmt));
exit(1);
}
/*
fetch data
*/
//bind result
MYSQL_BIND resbind[1];
unsigned long reslen=0;
resbind[0].buffer=0;
resbind[0].buffer_length=0;
resbind[0].length=&reslen;
if(mysql_stmt_bind_result(stmt,resbind)){
fprintf(stderr," mysql_stmt_bind_result(), failed\n");
fprintf(stderr, "%s\n",mysql_stmt_error(stmt));
exit(1);
}
mysql_stmt_fetch(stmt);
if (reslen > 0) //size of buffer?
{
char *data=(char*)malloc(reslen);
bind[0].buffer=data;
bind[0].buffer_length=reslen;
mysql_stmt_fetch_column(stmt, bind, 0, 0);
fprintf(stdout,"Result Len:%lu\nRegistation NR:%s",reslen,data);
free(data);
}
return "1";
}
The out is:
mysql_stmt_execute(), failed
Got packet bigger than 'max_allowed_packet' bytes
I think it's on here:
if(mysql_stmt_execute(stmt)){
fprintf(stderr," mysql_stmt_execute(), failed\n");
fprintf(stderr, "%s\n",mysql_stmt_error(stmt));
exit(1);
}
So,I created MYSQL_BIND and prepare to bind params (input).
Then I executed. It makes an error which I don't know what It is.
I'm googling how I can access a char* to see the current sql query for troubleshooting.
I think, you have a couple of errors:
1) your query has one (input) parameter and 2 (output) columns, but your defining just one MYSQL_BIND, maybe for input parameter.
2) when you initialize:
bind[0].buffer= 0;
bind[0].buffer_length= 0;
bind[0].length= &str_length;
if this bind is for input parameter, you must change to:
bind[0].buffer= token;
bind[0].buffer_length= strlen(token) + 1;
and pass it with this call:
mysql_stmt_bind_param(stmt,bind);
3) where is your mysql_stmt_execute command? fetch dont work is your query is not executed
I dont check fetch code, but it looks like fine (notice me if not)

connect remote sql (c language)

I cant connect remote mysql server. After I running the code use gcc, there is undefined reference to mysql
administrator#el6116-1:~$ gcc pilihan.c -o pilihan /tmp/cc4UQV0F.o: In
function `main': pilihan.c:(.text+0x67): undefined reference to
mysql_init' pilihan.c:(.text+0xe1): undefined reference to
mysql_real_connect' pilihan.c:(.text+0xf6): undefined reference to
mysql_error' pilihan.c:(.text+0x135): undefined reference to
mysql_query' pilihan.c:(.text+0x145): undefined reference to
mysql_error' pilihan.c:(.text+0x177): undefined reference to
mysql_use_result' pilihan.c:(.text+0x1c2): undefined reference to
mysql_fetch_row' pilihan.c:(.text+0x1d9): undefined reference to
mysql_free_result' pilihan.c:(.text+0x1e5): undefined reference to
mysql_close' collect2: error: ld returned 1 exit status
And here is my code in c:
#include <stdio.h>
#include <mysql/mysql.h>
#include <stdlib.h>
void DataA()
{
printf( "DataNasabah Dipilih..." );
}
void DataB()
{
printf( "AdminNasabah Dipilih..." );
}
main() {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "167.205.65.251";
char *user = "nasabah";
char *password = "123";
char *database = "wordpress";
conn = mysql_init(NULL);
int input;
printf("MySQl Client Alfred Saut Sibarani 23214038\n");
printf( "1. Data A\n" );
printf( "2. Data B\n" );
printf( "3. Keluar\n" );
printf( "Pilih Database: " );
scanf( "%d", &input );
/* Connection to Database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
/*If input =2 send mysql query*/
if (input == 2 && mysql_query(conn, "SELECT * FROM DataNasabah"))
{
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res = mysql_use_result(conn);
/* Show table output*/
printf("Data Nasabah:\n");
while ((row = mysql_fetch_row(res)) != NULL)
printf("%s %s %s\n", row[0],row[1],row[2]);
/* Close connection */
mysql_free_result(res);
mysql_close(conn);
}
#include <mysql/mysql.h>
Did not succeed. You will have to make sure the library is in place and is beeing properly linked.
undefined reference to
mysql_init' pilihan.c:(.text+0xe1)
Is a clear indicator that your linking of the library mysql.h failed.

Creating a test database in MySQL through C

I am getting a compilation error when I am trying to compile the following code.
#include "my_global.h"
#include "mysql.h"
int main(void)
{
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
if (mysql_real_connect(conn, "localhost", "zetcode",
"passwd", NULL, 0, NULL, 0) == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
if (mysql_query(conn, "create database testdb")) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
mysql_close(conn);
return 0;
}
I am using the Borland 32-bits compiler on Windows 7 to compile the following code. My command to compile looks like this
c:\Borland\BCC55>bcc32 -Ic:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2
-win32-vs2005\include -c creatingTESTDB.c
I am getting six compilation errors:
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
creatingTESTDB.c: Warning W8017
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs20
05\include\config-win.h 111: Redefinition of 'S_IRWXU' is not
identical Error E2238
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\config-win.h 114: Multiple declaration for 'mode_t'
Error E2344 c:\Borland\Bcc55\include\sys/types.h 35: Earlier
declaration of 'mod e_t' Error E2141
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\config-win.h 265: Declaration syntax error in function
double2ulonglong Error E2378
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\config-win.h 268: Return statement missing ; in function
double2ulonglo ng Error E2293
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\my_global.h 1591: ) expected in function rint Error
E2293
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\my_global.h 1595: ) expected in function rint
* 6 errors in Compile *
Any help would be greatly appreciated.
I am getting a compilation error when I am trying to compile the following code.
#include "my_global.h"
#include "mysql.h"
int main(void)
{
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
if (mysql_real_connect(conn, "localhost", "zetcode",
"passwd", NULL, 0, NULL, 0) == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
if (mysql_query(conn, "create database testdb")) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
mysql_close(conn);
return 0;
}
I am using the Borland 32-bits compiler on Windows 7 to compile the following code. My command to compile looks like this
c:\Borland\BCC55>bcc32 -Ic:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2
-win32-vs2005\include -c creatingTESTDB.c
I am getting six compilation errors:
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
creatingTESTDB.c:<br> Warning W8017
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs20
05\include\config-win.h 111: Redefinition of 'S_IRWXU' is not
identical<br><br> Error E2238
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\config-win.h 114: Multiple declaration for 'mode_t'<br><br>
Error E2344 c:\Borland\Bcc55\include\sys/types.h 35: Earlier
declaration of 'mod e_t'<br><br> Error E2141
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\config-win.h 265: Declaration syntax error in function
double2ulonglong<br><br> Error E2378
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\config-win.h 268: Return statement missing ; in function
double2ulonglo ng<br><br> Error E2293
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\my_global.h 1591: ) expected in function rint<br><br> Error
E2293
c:\Users\osho\Desktop\mysql-connector-c-noinstall-6.0.2-win32-vs2005
\include\my_global.h 1595: ) expected in function rint<br><br>
*** 6 errors in Compile ***
How can I fix this problem?
You did not give the version of MySQL you're using. Try adding the following header:
#include "my_sys.h"
Other sources to look at are:
Writing MySQL Programs Using C and
The MySQL C API.

mysql_rollback() not working

I had asked this question in another words in my last post and I didn't get the specific answer. So I rephrase. the rollback in the following code is not working. can you please tell me what is wrong:
//Creating and populating a table
C_P_table()
{
MYSQL *conn;
conn = mysql_init(NULL);
if (mysql_real_connect(conn, "localhost", "root",
"password", "testdb", 0, NULL, 0) == NULL) {
printf("Error2 %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
if (mysql_query(conn, "CREATE TABLE writers(name VARCHAR(25))")) {
printf("Error3 %u: %s\n", mysql_errno(conn), mysql_error(conn));
}
mysql_autocommit(conn,0);
if (mysql_query(conn,"START TRANSACTION")) {
printf("Error4 %u: %s\n", mysql_errno(conn), mysql_error(conn));
}
mysql_query(conn,"START TRANSACTION");
mysql_query(conn, "INSERT INTO writers VALUES('Leo Tolstoy')");
mysql_query(conn, "INSERT INTO writers VALUES('Jack London')");
mysql_query(conn, "INSERT INTO writers VALUES('Honore de Balzac')");
mysql_query(conn, "INSERT INTO writers VALUES('Lion Feuchtwanger')");
mysql_query(conn, "INSERT INTO writers VALUES('Emile Zola')");
if(!mysql_rollback(conn))
printf("Roll Back successful\n");
// mysql_query(conn,"ROLLBACK"); //doesn't work neither
mysql_close(conn);
}
int main(int argc, char **argv)
{
C_P_table();
}
My guess is that you are using MyISAM tables, normaly the default table type in MySQL.
So change the line
if (mysql_query(conn, "CREATE TABLE writers(name VARCHAR(25))"))
to
if (mysql_query(conn, "CREATE TABLE writers(name VARCHAR(25)) ENGINE = INNODB"))
and see whats happening.
See: http://dev.mysql.com/doc/refman/5.0/en/storage-engines.html