Installing MySQL Client Library
- Install MySQL Connector/C, which is the official C language client library provided by MySQL.
- Ensure that
libmysql.liband related header files are correctly added to the development environment.
Configuring the Compiler
In Visual Studio, you need to set the project properties to include the MySQL library files and header file paths.
- Additional Include Directories: Add the MySQL
includedirectory. - Additional Library Directories: Add the MySQL
libdirectory. - Additional Dependencies: Add
libmysql.lib.
Writing Code
- Include the necessary header files.
- Connect to the database.
- Execute SQL commands.
- Process the result set.
- Close the connection.
Below is a simple example demonstrating how to connect to a MySQL database using C and execute a query:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h> // MySQL client library header file
int main() {
MYSQL *conn; // MySQL connection handle
MYSQL_RES *res; // Result set
MYSQL_ROW row; // Row pointer
const char *server = "localhost";
const char *user = "your_username";
const char *password = "your_password";
const char *database = "your_database";
conn = mysql_init(NULL); // Initialize connection
if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
mysql_close(conn);
return 1;
}
// Query statement
const char *sql = "SELECT * FROM your_table";
// Execute query
if (mysql_query(conn, sql)) {
fprintf(stderr, "%s\n", mysql_error(conn));
mysql_close(conn);
return 1;
}
// Get result set
res = mysql_use_result(conn);
// Output results
while ((row = mysql_fetch_row(res)) != NULL) {
int i;
for (i = 0; i < mysql_num_fields(res); i++) {
printf("%s ", row[i] ? row[i] : "(null)");
}
printf("\n");
}
// Clean up resources
mysql_free_result(res);
mysql_close(conn);
return 0;
}
Error Handling
In practical applications, error checking should be performed on every operation that may fail to ensure program robustness and reliability. For example, after connecting to the database, executing queries, etc., you should check for errors.
Dynamic Input Parameters
To improve program flexibility, users can specify database connection information and query statements through command-line arguments or interactive input.
More Complex SQL Operations
In addition to basic queries, you can also implement insert, update, and delete operations.
Example code: Includes error handling and dynamic input
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>
void handle_mysql_error(MYSQL *conn) {
fprintf(stderr, "MySQL Error: %s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
int main(int argc, char *argv[]) {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
if (argc != 6) {
fprintf(stderr, "Usage: %s host user password db query\n", argv[0]);
exit(1);
}
const char *server = argv[1];
const char *user = argv[2];
const char *password = argv[3];
const char *database = argv[4];
const char *query = argv[5];
conn = mysql_init(NULL);
if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
handle_mysql_error(conn);
}
if (mysql_query(conn, query)) {
handle_mysql_error(conn);
}
res = mysql_use_result(conn);
while ((row = mysql_fetch_row(res)) != NULL) {
int i;
for (i = 0; i < mysql_num_fields(res); i++) {
printf("%s ", row[i] ? row[i] : "(null)");
}
printf("\n");
}
mysql_free_result(res);
mysql_close(conn);
return 0;
}
Explanation
- Error handling function
handle_mysql_error: Called when a MySQL operation fails, prints the error message and exits the program. - Dynamic input parameters: The program accepts five command-line arguments corresponding to hostname, username, password, database name, and SQL query statement.
- Command-line argument validation: If the number of arguments is incorrect, output usage help and exit.
- SQL query: Retrieve the query statement from command-line arguments and execute it.
Compiling and Running
Compile command:
gcc -o myapp myapp.c -lmysqlclient
Run command:
./myapp localhost root password mydb "SELECT * FROM your_table"
Extended Features
Insert data:
const char *insert_sql = "INSERT INTO your_table (column1, column2) VALUES ('value1', 'value2')";
if (mysql_query(conn, insert_sql)) {
handle_mysql_error(conn);
}
Update data:
const char *update_sql = "UPDATE your_table SET column1 = 'new_value' WHERE id = 1";
if (mysql_query(conn, update_sql)) {
handle_mysql_error(conn);
}
Delete data:
const char *delete_sql = "DELETE FROM your_table WHERE id = 1";
if (mysql_query(conn, delete_sql)) {
handle_mysql_error(conn);
}
Parameterized Queries
Using prepared statements can effectively prevent SQL injection attacks. Below is an example using prepared statements:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>
void handle_mysql_error(MYSQL *conn) {
fprintf(stderr, "MySQL Error: %s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
int main(int argc, char *argv[]) {
MYSQL *conn;
MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
MYSQL_RES *res;
MYSQL_ROW row;
int param1, param2;
if (argc != 6) {
fprintf(stderr, "Usage: %s host user password db query\n", argv[0]);
exit(1);
}
const char *server = argv[1];
const char *user = argv[2];
const char *password = argv[3];
const char *database = argv[4];
const char *query = argv[5];
conn = mysql_init(NULL);
if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
handle_mysql_error(conn);
}
stmt = mysql_stmt_init(conn);
// Prepare the prepared statement
const char *sql = "SELECT * FROM your_table WHERE column1 = ? AND column2 = ?";
if (mysql_stmt_prepare(stmt, sql, strlen(sql))) {
handle_mysql_error(conn);
}
// Set bind parameters
param1 = 1;
param2 = 2;
bind[0].buffer_type = MYSQL_TYPE_LONG;
bind[0].buffer = ¶m1;
bind[0].is_null = 0;
bind[0].length = 0;
bind[1].buffer_type = MYSQL_TYPE_LONG;
bind[1].buffer = ¶m2;
bind[1].is_null = 0;
bind[1].length = 0;
// Bind parameters
if (mysql_stmt_bind_param(stmt, bind)) {
handle_mysql_error(conn);
}
// Execute the prepared statement
if (mysql_stmt_execute(stmt)) {
handle_mysql_error(conn);
}
// Get result set
if (mysql_stmt_store_result(stmt)) {
handle_mysql_error(conn);
}
// Output results
while (mysql_stmt_fetch(stmt)) {
// Get column values
// Assuming column names are column1 and column2
MYSQL_BIND *bind = mysql_stmt_fetch_column(stmt, 0, 0);
printf("Column1: %ld, Column2: %ld\n", *(long *)bind[0].buffer, *(long *)bind[1].buffer);
}
mysql_stmt_close(stmt);
mysql_close(conn);
return 0;
}
Transaction Management
Transaction management ensures that a group of operations either all succeed or all fail. Below is an example using transactions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>
void handle_mysql_error(MYSQL *conn) {
fprintf(stderr, "MySQL Error: %s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
int main(int argc, char *argv[]) {
MYSQL *conn;
MYSQL_STMT *stmt;
MYSQL_RES *res;
MYSQL_ROW row;
if (argc != 6) {
fprintf(stderr, "Usage: %s host user password db query\n", argv[0]);
exit(1);
}
const char *server = argv[1];
const char *user = argv[2];
const char *password = argv[3];
const char *database = argv[4];
const char *query = argv[5];
conn = mysql_init(NULL);
if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
handle_mysql_error(conn);
}
// Start transaction
if (mysql_query(conn, "START TRANSACTION")) {
handle_mysql_error(conn);
}
// Insert data
const char *insert_sql = "INSERT INTO your_table (column1, column2) VALUES ('value1', 'value2')";
if (mysql_query(conn, insert_sql)) {
handle_mysql_error(conn);
}
// Update data
const char *update_sql = "UPDATE your_table SET column1 = 'new_value' WHERE id = 1";
if (mysql_query(conn, update_sql)) {
handle_mysql_error(conn);
}
// Commit transaction
if (mysql_query(conn, "COMMIT")) {
handle_mysql_error(conn);
}
mysql_close(conn);
return 0;
}
Calling Stored Procedures
Stored procedures can execute complex logic on the server side, improving performance and security. Below is an example of calling a stored procedure:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>
void handle_mysql_error(MYSQL *conn) {
fprintf(stderr, "MySQL Error: %s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
int main(int argc, char *argv[]) {
MYSQL *conn;
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
MYSQL_RES *res;
MYSQL_ROW row;
if (argc != 6) {
fprintf(stderr, "Usage: %s host user password db query\n", argv[0]);
exit(1);
}
const char *server = argv[1];
const char *user = argv[2];
const char *password = argv[3];
const char *database = argv[4];
const char *query = argv[5];
conn = mysql_init(NULL);
if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
handle_mysql_error(conn);
}
stmt = mysql_stmt_init(conn);
// Prepare to call stored procedure
const char *call_procedure = "CALL your_procedure(?)";
if (mysql_stmt_prepare(stmt, call_procedure, strlen(call_procedure))) {
handle_mysql_error(conn);
}
// Set bind parameters
int param = 1;
bind[0].buffer_type = MYSQL_TYPE_LONG;
bind[0].buffer = ¶m;
bind[0].is_null = 0;
bind[0].length = 0;
// Bind parameters
if (mysql_stmt_bind_param(stmt, bind)) {
handle_mysql_error(conn);
}
// Execute stored procedure
if (mysql_stmt_execute(stmt)) {
handle_mysql_error(conn);
}
mysql_stmt_close(stmt);
mysql_close(conn);
return 0;
}



