程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Linux下C語言執行MySQL語句

Linux下C語言執行MySQL語句

編輯:MySQL綜合教程

執行SQL語句的增、刪、改、查的主要API函數為:

int mysql_query(MYSQL *connection, const char *query);

函數接收參數連接句柄和字符串形式的有效SQL語句(沒有結束的分號,這與mysql工具不同)。如果成功,它返回0。

如果包含二進制數據的查詢,要使用mysql_real_query.

檢查受查詢影響的行數:

my_ulonglong mysql_affected_rows(MYSQL *connection);
my_ulonglong是無符號長整形,為%lu格式
這個函數返回受之前執行update,insert或delete查詢影響的行數。

例子

數據庫中有一個student表

 

CREATE TABLE student (
		student_no varchar(12) NOT NULL PRIMARY KEY,
		student_name varchar(12) NOT NULL
		);
 
\

增、刪、改代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mysql.h"
#include "errmsg.h"
#include "mysqld_error.h"

MYSQL conn;

void connection(const char* host, const char* user, const char* password, const char* database) {
	mysql_init(&conn); // 注意取地址符&

	if (mysql_real_connect(&conn, host, user, password, database, 0, NULL, 0)) {
		printf("Connection success!\n");
	} else {
		fprintf(stderr, "Connection failed!\n");
		if (mysql_errno(&conn)) {
			fprintf(stderr, "Connection error %d: %s\n", mysql_errno(&conn), mysql_error(&conn));
		}
		exit(EXIT_FAILURE);
	}
}

void insert() {
	int res = mysql_query(&conn, "INSERT INTO student(student_no,student_name) VALUES('123465', 'Ann')");
	if (!res) {
		printf("Inserted %lu rows\n", (unsigned long)mysql_affected_rows(&conn));
	} else {
		fprintf(stderr, "Insert error %d: %s\n", mysql_errno(&conn), mysql_error(&conn));
	}
}

void update() {
	int res = mysql_query(&conn, "UPDATE student SET student_name='Anna' WHERE student_no='123465'");
	if (!res) {
		printf("Update %lu rows\n", (unsigned long)mysql_affected_rows(&conn));
	} else {
		fprintf(stderr, "Update error %d: %s\n", mysql_errno(&conn), mysql_error(&conn));
	}
}

void delete() {
	int res = mysql_query(&conn, "DELETE from student WHERE student_no='123465'");
	if (!res) {
		printf("Delete %lu rows\n", (unsigned long)mysql_affected_rows(&conn));
	} else {
		fprintf(stderr, "Delete error %d: %s\n", mysql_errno(&conn), mysql_error(&conn));
	}
}

int main (int argc, char *argv[]) {

	connection("localhost", "root", "shuang", "shuangde");
	delete();
	mysql_close(&conn);
	exit(EXIT_SUCCESS);
}

返回數據的語句:select

SQL最常見的用法是提取數據而不是插入或更新數據。數據是用select語句提取的

C應用程序提取數據一般需要4個步驟:

1、執行查詢

2、提取數據

3、處理數據

4、必要的清理工作

就像之前的insert和update一樣,使用mysql_query來發送SQL語句,然後使用mysql_store_result或mysql_use_result來提取數據,具體使用哪個語句取決於你想如何提取數據。接著,將使用一系列mysql_fetch_row來處理數據。最後,使用mysql_free_result釋放查詢占用的內存資源。

一次提取所有數據:mysql_store_result

// 相關函數:

// 這是在成功調用mysql_query之後使用此函數,這個函數將立刻保存在客戶端中返回的所有數據。它返回一個指向結果集結構的指針,如果失敗返回NULL
MYSQL_RES *mysql_store_result(MYSQL *connection);

// 這個函數接受由mysql_store_result返回的結果結構集,並返回結構集中的行數
my_ulonglong mysql_num_rows(MYSQL_RES *result);


// 這個函數從使用mysql_store_result得到的結果結構中提取一行,並把它放到一個行結構中。當數據用完或發生錯誤時返回NULL.
MYSQL_ROW mysql_fetch_row(MYSQL_RES *resutl);


// 這個函數用來在結果集中跳轉,設置將會被下一個mysql_fetch_row操作返回的行。參數offset是一個行號,它必須是在0~結果總行數-1的范圍內。傳遞
// 0將會導致下一個mysql_fetch_row調用返回結果集中的第一行。
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);


// 返回一個偏移值,它用來表示結果集中的當前位置。它不是行號,不能把它用於mysql_data_seek
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);


// 這將在結果集中移動當前的位置,並返回之前的位置
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);


// 完成所有對數據的操作後,必須總是調用這個來善後處理
void mysql_free_result(MYSQL_RES *result);

示例代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mysql.h"
#include "errmsg.h"
#include "mysqld_error.h"


MYSQL conn;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;

void connection(const char* host, const char* user, const char* password, const char* database) {
	mysql_init(&conn); // 注意取地址符&

	if (mysql_real_connect(&conn, host, user, password, database, 0, NULL, 0)) {
		printf("Connection success!\n");
	} else {
		fprintf(stderr, "Connection failed!\n");
		if (mysql_errno(&conn)) {
			fprintf(stderr, "Connection error %d: %s\n", mysql_errno(&conn), mysql_error(&conn));
		}
		exit(EXIT_FAILURE);
	}
}

int main (int argc, char *argv[]) {

	connection("localhost", "root", "shuang", "shuangde");
	int res = mysql_query(&conn, "SELECT * from student");
	if (res) {
		fprintf(stderr, "SELECT error: %s\n", mysql_error(&conn));
	} else {
		res_ptr = mysql_store_result(&conn);
		if (res_ptr) {
			printf("Retrieved %lu rows\n", (unsigned long)mysql_num_rows(res_ptr));	
			while ((sqlrow = mysql_fetch_row(res_ptr))) {
				printf("Fetched data...\n")	;
			}
			if (mysql_errno(&conn)) {
				fprintf(stderr, "Retrive error: %s\n", mysql_error(&conn));
			}
			mysql_free_result(res_ptr);
		} 
	}
	mysql_close(&conn);
	exit(EXIT_SUCCESS);
}

一次提取一行數據:mysql_use_result

使用方法和mysql_store_result完全一樣,把上面代碼的mysql_store_result改為mysql_use_result即可。

mysql_use_result具備資源管理方面的實質性好處,更好地平衡了網絡負載,以及減少了可能非常大的數據帶來的存儲開銷,但是不能與mysql_data_seek、mysql_row_seek、mysql_row_tell、mysql_num_rows一起使用。如果數據比較少,用mysql_store_result更好。

處理返回的數據

// 相關函數和定義:


// 返回結果集中的字段(列)數目
unsigned int mysql_field_count(MYSQL *connection);

// 將元數據和數據提取到一個新的結構中
MYSQL_FIELD *mysql_fetch_field(MYSQL *result);

// 這個函數用來覆蓋當前的字段編號,該編號會隨著每次mysql_fetch_field調用而自動增加。如果給offset傳遞0,那麼將跳回第1列
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL *result, MYSQL_FIELD_OFFSET offset);


// MYSQL_FIELD定義在sql.h中,是指向字段結構數據的指針,有關於列的信息。有成員:
char *name;		// 列名,為字符串
char *table;	// 列所屬表名
char *def;		// 如果調用mysql_list_fields,它將包含該列的默認值
enum enum_field_types type;  // 列類型
unsigned int length;		 // 列寬
unsigned int max_length;	 // 如果使用mysql_store_result,它將包含以字節為單位的提取的最長列值的長度,如果使用mysql_use_result,將不會被設置
unsigned int flags;			 // 關於列定義的標志,與得到的數據無關.常見的標志的含義有:
						     //	NOT_NULL_FLAG
							 // PRI_KEY_FLAG
						     //	UNSIGNED_FLAG
							 // AUTO_INCREMENT_FLAG
							 // BINARY_FLAG等
unsigned int decimals;		 // 小數點後的數字個數。


// 列類型相當廣泛,完整的列表見頭文件mysql_com.h,常見的有:
//	FIELD_TYPE_DECIMAL
//	FIELD_TYPE_LONG
//	FIELD_TYPE_STRING
//	FIELD_TYPE_VAR_STRING

//一個特別有用的預定義宏: IS_NUM,當字段類型為數字時,返回true

代碼示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mysql.h"
#include "errmsg.h"
#include "mysqld_error.h"


MYSQL conn;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;

void connection(const char* host, const char* user, const char* password, const char* database) {
	mysql_init(&conn); // 注意取地址符&

	if (mysql_real_connect(&conn, host, user, password, database, 0, NULL, 0)) {
		printf("Connection success!\n");
	} else {
		fprintf(stderr, "Connection failed!\n");
		if (mysql_errno(&conn)) {
			fprintf(stderr, "Connection error %d: %s\n", mysql_errno(&conn), mysql_error(&conn));
		}
		exit(EXIT_FAILURE);
	}
}

void display_row() {
	unsigned int field_count = mysql_field_count(&conn);
	int i = 0;
	while (i < field_count) {
		if (sqlrow[i]) printf("%s ", sqlrow[i]);
		else printf("NULL");
		i++;
	}
	printf("\n");
}

void display_header() {
	MYSQL_FIELD *field_ptr;
	printf("Column details:\n");
	while ((field_ptr = mysql_fetch_field(res_ptr)) != NULL) {
		printf("\t Name: %s\n", field_ptr->name);	
		printf("\t Table: %s\n", field_ptr->table);	
		printf("\t Type: ");
		if (IS_NUM(field_ptr->type)) {
			printf("Numeric field\n");	
		} else {
			switch(field_ptr->type) {
				case FIELD_TYPE_VAR_STRING:
					printf("VARCHAR\n");
					break;
				case FIELD_TYPE_LONG:
					printf("LONG");
					break;
				default:
					printf("Type is %d, check in msyql_com.h\n", field_ptr->type);
			}	
		}
		printf("\t Max width %ld\n", field_ptr->length);
		if (field_ptr->flags & AUTO_INCREMENT_FLAG)
			printf("\t Auto increments\n");
		printf("\n");
	}
}

int main (int argc, char *argv[]) {

	connection("localhost", "root", "shuang", "shuangde");
	int res = mysql_query(&conn, "SELECT * from student");
	if (res) {
		fprintf(stderr, "SELECT error: %s\n", mysql_error(&conn));
	} else {
		res_ptr = mysql_use_result(&conn);
		if (res_ptr) {
			int first = 1;
			while ((sqlrow = mysql_fetch_row(res_ptr))) {
				if (first) {
					display_header();
					first = 0;	
				}
				display_row();
			}
			if (mysql_errno(&conn)) {
				fprintf(stderr, "Retrive error: %s\n", mysql_error(&conn));
			}
			mysql_free_result(res_ptr);
		} 
	}
	mysql_close(&conn);
	exit(EXIT_SUCCESS);
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved