Mysql数据库的api介绍

链接的流程图

这里写图片描述

一,API介绍

1,初始化函数

MYSQL *mysql_init(MYSQL *mysql)

mysql 可以传 NULL

返回 分配的句柄 MYSQL*指针

2,连接到mysql数据库

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)

参数介绍

  1. mysql 初始化的句柄指针
  2. host 主机地址
  3. user 用户名 – mysql数据库 root
  4. passwd 用户的密码
  5. db 要连接的数据库
  6. port 端口 一般填0,mysql默认端口 3306
  7. unix_socket 本地套接字 ,一般填NULL
  8. client_flag 连接标志 一般填0

返回值: 成功返回 连接句柄,失败返回 NULL

3,设定登陆的字符集 – 登陆之后

int mysql_set_character_set(MYSQL *mysql, char *csname)

参数:

  1. mysql 连接句柄
  2. csname 字符集的名称 utf8
4,query功能非常强大 增删改查都可以

int mysql_query(MYSQL *mysql, const char *query)

参数介绍:

  1. mysql 连接句柄
  2. query 执行的sql

返回值:

成功 返回 0
失败 返回 非0
5,获得结果集的函数

MYSQL_RES *mysql_store_result(MYSQL *mysql)

返回值: 如果读取结果集失败,mysql_store_result()还会返回Null指针。通过检查mysql_error()是否返回非空字符串,mysql_errno()是否返回非0值,或mysql_field_count()是否返回0,可以检查是否出现了错误。

6,释放结果集

void mysql_free_result(MYSQL_RES *result)

7,获取查询的显示列的长度

unsigned int mysql_num_fields(MYSQL_RES *result)

描述

返回结果集中的行数。

注意,你可以从指向结果集的指针或指向连接句柄的指针获得行数。如果mysql_store_result()或mysql_use_result()返回NULL,应使用连接句柄(因而没有结果集指针)。在该情况下,可调用mysql_field_count()来判断mysql_store_result()是否生成了非空结果。这样,客户端程序就能采取恰当的行动,而不需要知道查询是否是SELECT语句(或类似SELECT的语句)。在下面的示例中,介绍了执行该操作的方式。

8,获取列信息

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

描述

返回采用MYSQL_FIELD结构的结果集的列。重复调用该函数,以检索关于结果集中所有列的信息。未剩余字段时,mysql_fetch_field()返回NULL。

每次执行新的SELECT查询时,将复位mysql_fetch_field(),以返回关于第1个字段的信息。调用mysql_field_seek()也会影响mysql_fetch_field()返回的字段。

如果调用了mysql_query()以在表上执行SELECT,但未调用mysql_store_result(),如果调用了mysql_fetch_field()以请求BLOB字段的长度,MySQL将返回默认的Blob长度(8KB)。之所以选择8KB是因为MySQL不知道BLOB的最大长度。应在日后使其成为可配置的。一旦检索了结果集,field->max_length将包含特定查询中该列的最大值的长度。

返回值

当前列的MYSQL_FIELD结构。如果未剩余任何列,返回NULL。

9,取出一行信息

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

描述

检索结果集的下一行。在mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL。在mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,mysql_fetch_row()返回NULL。

行内值的数目由mysql_num_fields(result)给出。如果行中保存了调用mysql_fetch_row()返回的值,将按照row[0]到row[mysql_num_fields(result)-1],访问这些值的指针。行中的NULL值由NULL指针指明。

可以通过调用mysql_fetch_lengths()来获得行中字段值的长度。对于空字段以及包含NULL的字段,长度为0。通过检查字段值的指针,能够区分它们。如果指针为NULL,字段为NULL,否则字段为空。

返回值

下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL。

10,显示受影响的行数

my_ulonglong mysql_affected_rows(MYSQL *mysql)

描述

返回上次UPDATE更改的行数,上次DELETE删除的行数,或上次INSERT语句插入的行数。对于UPDATE、DELETE或INSERT语句,可在mysql_query()后立刻调用。对于SELECT语句,mysql_affected_rows()的工作方式与mysql_num_rows()类似。

返回值

大于0的整数表明受影响或检索的行数。“0”表示UPDATE语句未更新记录,在查询中没有与WHERE匹配的行,或未执行查询。“-1”表示查询返回错误,或者,对于SELECT查询,在调用mysql_store_result()之前调用了mysql_affected_rows()。由于mysql_affected_rows()返回无符号值,通过比较返回值和“(my_ulonglong)-1”或等效的“(my_ulonglong)~0”,检查是否为“-1”。

gcc -o connect mysql.c -lmysqlclient -I/usr/include/mysql -L/usr/lib64/mysql/
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>
#include <unistd.h>

#define _USER_ "root" //用户名
#define _HOST_ "127.0.0.1" //host
#define _PASSWD_ "123"   //root 用户名密码
#define _DB_ "scott" //库名
#define _PORT_ 3306  //port

//打印信息   结果集
void show_information(MYSQL_RES * res, MYSQL *mysql)
{
	int i;
	MYSQL_ROW row; //
	//unsigned long *lengths;
	unsigned int num_fields;
	MYSQL_FIELD *field; //字段名
	
	
	// 数据的长度unsigned int mysql_num_fields(MYSQL_RES *result) 
	num_fields = mysql_num_fields(res);
	//返回列长unsigned long *mysql_fetch_lengths(MYSQL_RES *result) 
	//lengths  = mysql_fetch_lengths(res);
	printf("num_fields = [%d]\n", num_fields);
	//字段名
	for (i = 0; i < num_fields, field = mysql_fetch_field(res); i++) {
				 printf(" %s\t", field->name);
	}
	printf("\n");
	printf("--------------------------------------------------------------\n");
	while ((row = mysql_fetch_row(res))) {
			for (i = 0; i < num_fields; i++) {
						printf("%s \t", row[i] ? row[i] : NULL);
			}
			printf("\n");
	}
	//释放结果集
	mysql_free_result(res);
	printf("--------------------------------------------------------------\n");
	//显示受影响的行数
	printf("  %ld rows in set\n", (long) mysql_affected_rows(mysql));	
	
}

int main(int argc, char *argv[])
{
	int ret, i;
	MYSQL *mysql;
	MYSQL_RES * res;
	char strsql[512] = { 0};
	
	

	//1,mysql_init 初始化
	mysql = mysql_init(NULL);
	if (mysql == NULL) {
		printf("mysql_init error\n");
		return -1;
	}

	//2,mysql_real_connect链接
	mysql = mysql_real_connect(mysql, 
	_HOST_, 
	_USER_, 
	_PASSWD_, 
	_DB_, 
	0, 
	NULL, 
	0);

	if (mysql == NULL) {
		printf("mysql_real_connect error\n");
		return -1;
	}

	printf("connect mysql ok\n");

	//处理字符问题的函数
	if ( mysql_set_character_set(mysql, "utf8") != 0) {
		printf(" mysql_set_character_set error\n");
		mysql_close(mysql);
		exit(1);
	} 
	//===========================输入sql语句======================

	while (1) {
			memset(strsql, 0x00, sizeof(strsql));
			write(STDOUT_FILENO, "yoursql>", 8);
			
			//读取client输入的sql字符串
			read(STDIN_FILENO, strsql, sizeof(strsql));
			
			//退出的处理
			if (strncasecmp(strsql, "quit", 4) == 0) {
					printf("client 退出处理\n");
					break;	
			}	
			
		//输入sql的
		ret = mysql_query(mysql, strsql);
		if (ret) {
			printf("mysql_query error\n");
			continue;
		}
	
		res = mysql_store_result(mysql);
			//有结果集的处理
		if (res != NULL) {
			show_information(res, mysql);
		}
		else {
			//显示受影响的行数
			printf(" Query OK, %ld row affected\n",(long) mysql_affected_rows(mysql));	
		}
		
	
	}




//	char sqlstr[] = "select *from emp";
//	//查询语句int mysql_query(MYSQL *mysql, const char *query) 
//	ret = mysql_query(mysql, sqlstr);
//	if (ret) {
//		printf("mysql_query error\n");
//		return -1;	
//	}
//	
//	//查询的结果集MYSQL_RES *mysql_store_result(MYSQL *mysql) 
//	res = mysql_store_result(mysql);

	//MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) 
//	if ( res != NULL) {
//		show_information(res);
//			// 数据的长度unsigned int mysql_num_fields(MYSQL_RES *result) 
//			num_fields = mysql_num_fields(res);
//			//返回列长unsigned long *mysql_fetch_lengths(MYSQL_RES *result) 
//			//lengths  = mysql_fetch_lengths(res);
//			printf("num_fields = [%d]\n", num_fields);
//			//字段名
//			for (i = 0; i < num_fields, field = mysql_fetch_field(res); i++) {
//						 printf(" %s\t", field->name);
//			}
//			printf("\n");
//			while (row = mysql_fetch_row(res)) {
//				
//				for (i = 0; i < num_fields; i++) {
//							printf("%s \t", row[i]);
//				}
//				printf("\n");
//			}
//				//释放结果集
// 		 mysql_free_result(res);
//	}

	
	
	//关闭mysql
	mysql_close(mysql);
     	 return 0;
}

这里写图片描述

二,SQL预处理 防止注入和增加效率

1,插入预处理

流程图

这里写图片描述

这里写图片描述

原理
这里写图片描述

①api介绍
1,预处理初始化

MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)

描述

创建MYSQL_STMT句柄。对于该句柄,应使用mysql_stmt_close(MYSQL_STMT *)释放。

返回值

成功时,返回指向MYSQL_STMT结构的指针。如果内存溢出,返回NULL。

2,插入预处理语句

int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length)

描述

给定mysql_stmt_init()返回的语句句柄,准备字符串查询指向的SQL语句,并返回状态值。字符串长度应由“length”参量给出。字符串必须包含1条SQL语句。不应为语句添加终结用分号(‘;’)或\g。

通过将问号字符“?”嵌入到SQL字符串的恰当位置,应用程序可包含SQL语句中的一个或多个参数标记符。

标记符仅在SQL语句中的特定位置时才是合法的。例如,它可以在INSERT语句的VALUES()列表中(为行指定列值),或与WHERE子句中某列的比较部分(用以指定比较值)。但是,对于ID(例如表名或列名),不允许使用它们,不允许指定二进制操作符(如等于号“=”)的操作数。后一个限制是有必要的,原因在于,无法确定参数类型。一般而言,参数仅在DML(数据操作语言)语句中才是合法的,在DDL(数据定义语言)语句中不合法。

执行语句之前,必须使用mysql_stmt_bind_param(),将参数标记符与应用程序变量绑定在一起。

返回值

如果成功处理了语句,返回0。如果出现错误,返回非0值。

3,获取参数

unsigned long mysql_stmt_param_count(MYSQL_STMT *stmt)

描述

返回预处理语句中参数标记符的数目。

返回值

表示语句中参数数目的无符号长整数。

4,参数的绑定

my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)

描述

mysql_stmt_bind_param()用于为SQL语句中的参数标记符绑定数据,以传递给mysql_stmt_prepare()。它使用MYSQL_BIND结构来提供数据。“bind”是MYSQL_BIND结构的某一数组的地址。按照客户端库的预期,对于查询中出现的每个“?”参数标记符,数组中均包含1个元素。

假定你准备了下述语句:

INSERT INTO mytbl VALUES(?,?,?)
绑定参数时,MYSQL_BIND结构的数组包含3个元素,并能声明如下:

MYSQL_BIND bind[3];

5,预处理执行

int mysql_stmt_execute(MYSQL_STMT *stmt)

描述

mysql_stmt_execute()执行与语句句柄相关的预处理查询。在该调用期间,将当前绑定的参数标记符的值发送到服务器,服务器用新提供的数据替换标记符。

如果语句是UPDATE、DELETE或INSERT,通过调用mysql_stmt_affected_rows(),可发现更改、删除或插入的总行数。如果这是诸如SELECT等能生成结果集的语句,调用任何其他能导致查询处理的函数之前,必须调用mysql_stmt_fetch()来获取数据。关于如何获取结果的更多信息,请参见25.2.7.11节,“mysql_stmt_fetch()”。

对于生成结果集的语句,执行语句之前,可通过调用mysql_stmt_attr_set(),请求mysql_stmt_execute()为语句打开光标。如果多次执行某一语句,在打开新的光标前,mysql_stmt_execute()将关闭任何已打开的光标。

返回值

如果执行成功,返回0。如果出现错误,返回非0值。

6,返回预处理的行数

my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)

描述

返回上次执行语句更改、删除或插入的总行数。对于UPDATE、DELETE或INSERT语句,可在mysql_stmt_execute()之后立刻调用它们。对于SELECT语句,mysql_stmt_affected_rows()的工作方式类似于mysql_num_rows()。

返回值

大于0的整数指明了受影响或检索的行数。对于UPDATE语句,“0”表明未更新任何记录,在查询中没有与WHERE子句匹配的行,或尚未执行任何查询。“-1”表明返回了错误,或对SELECT查询,在调用mysql_stmt_store_result()之前调用了mysql_stmt_affected_rows()。由于mysql_stmt_affected_rows()返回无符号值,可通过比较返回值和“(my_ulonglong)-1”(或等效的“(my_ulonglong)~0”),检查“-1”。

//预处理方式api处理 -- insert 
#include <stdio.h>
#include "mysql.h"
#include <stdlib.h>
#include <string.h>

#define _HOST_ "localhost"  //主机
#define _USER_ "root"       //mysql用户,非主机
#define _PASSWD_ "123"   //密码
#define _DBNAME_ "scott"    //库名

#define STRING_SIZE 50
 
#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"  // if EXISTS 好处 是如果表不存在,执行不会报错
#define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\
                                                 col2 VARCHAR(40),\
                                                 col3 SMALLINT,\
                                                 col4 TIMESTAMP)"
#define INSERT_SAMPLE "INSERT INTO test_table(col1,col2,col3) VALUES(?,?,?)"
void prepare_insert(MYSQL *mysql);

int main()
{
	//1.初始化
	MYSQL * mysql = NULL;
	mysql = mysql_init(NULL) ;
	if(mysql == NULL )
	{
		printf("mysql init err\n");
		exit(1);
	}
	//2.连接
	mysql = mysql_real_connect(mysql, _HOST_,_USER_, _PASSWD_,_DBNAME_, 0, NULL,0);
	if(mysql == NULL)
	{
		printf("mysql_real_connect connect err\n");
		exit(1);
	}
	printf("welcome to mysql \n");
	prepare_insert(mysql);
	//3.关闭
    mysql_close(mysql);
    return 0;
}




void prepare_insert(MYSQL *mysql)
{
	MYSQL_STMT    *stmt;//预处理的句柄 -- 标识进程内唯一的一个预处理的sql
	MYSQL_BIND    bind[3];//绑定变量 
	my_ulonglong  affected_rows;
	int           param_count;
	short         small_data;
	int           int_data;
	char          str_data[STRING_SIZE];
	unsigned long str_length;
	my_bool       is_null;
	 
	if (mysql_query(mysql, DROP_SAMPLE_TABLE))//删除表
	{
	  fprintf(stderr, " DROP TABLE failed\n");
	  fprintf(stderr, " %s\n", mysql_error(mysql));
	  exit(0);
	}
	 
	if (mysql_query(mysql, CREATE_SAMPLE_TABLE))//创建表
	{
	  fprintf(stderr, " CREATE TABLE failed\n");
	  fprintf(stderr, " %s\n", mysql_error(mysql));
	  exit(0);
	}
	 
	/* Prepare an INSERT query with 3 parameters */
	/* (the TIMESTAMP column is not named; the server */
	/*  sets it to the current date and time) */
	stmt = mysql_stmt_init(mysql); //预处理的初始化
	if (!stmt)
	{
	  fprintf(stderr, " mysql_stmt_init(), out of memory\n");
	  exit(0);
	}
	if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE))) //insert 语句 的预处理 
	{
	  fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");
	  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
	  exit(0);
	}
	fprintf(stdout, " prepare, INSERT successful\n");
	 
	/* Get the parameter count from the statement */
	param_count= mysql_stmt_param_count(stmt);//获得参数个数 
	fprintf(stdout, " total parameters in INSERT: %d\n", param_count);
	 
	if (param_count != 3) /* validate parameter count */
	{
	  fprintf(stderr, " invalid parameter count returned by MySQL\n");
	  exit(0);
	}
	 
	/* Bind the data for all 3 parameters */
	 
	memset(bind, 0, sizeof(bind));
	 
	/* INTEGER PARAM */
	/* This is a number type, so there is no need to specify buffer_length */
	bind[0].buffer_type= MYSQL_TYPE_LONG;//对应int类型
	bind[0].buffer= (char *)&int_data;//内存地址的映射 
	bind[0].is_null= 0;
	bind[0].length= 0;
	 
	/* STRING PARAM */
	bind[1].buffer_type= MYSQL_TYPE_STRING;
	bind[1].buffer= (char *)str_data;//char 100 
	bind[1].buffer_length= STRING_SIZE;
	bind[1].is_null= 0;
	bind[1].length= &str_length;
	 
	/* SMALLINT PARAM */
	bind[2].buffer_type= MYSQL_TYPE_SHORT;
	bind[2].buffer= (char *)&small_data;
	bind[2].is_null= &is_null;//是否为null的指示器 
	bind[2].length= 0;
	 
	/* Bind the buffers */
	if (mysql_stmt_bind_param(stmt, bind)) //绑定变量 参数绑定
	{
	  fprintf(stderr, " mysql_stmt_bind_param() failed\n");
	  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
	  exit(0);
	}
	 
	//第一波赋值 
	int_data= 10;             /* integer */
	strncpy(str_data, "MySQL", STRING_SIZE); /* string  */
	str_length= strlen(str_data);
	
	//INSERT INTO test_table(col1,col2,col3) VALUES(10,'MySQL',null)
	
	 
	/* INSERT SMALLINT data as NULL */
	is_null= 1;//指示插入的第三个字段是否为null 
	//insert into test_table(col1,col2,col3) values(10,'MySQL',null);
	 
	/* Execute the INSERT statement - 1*/
	if (mysql_stmt_execute(stmt)) //预处理的执行,第一次执行 
	{
	  fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");
	  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
	  exit(0);
	}
	 
	/* Get the total number of affected rows */
	affected_rows= mysql_stmt_affected_rows(stmt);//预处理的影响条数
	fprintf(stdout, " total affected rows(insert 1): %lu\n",
	                (unsigned long) affected_rows);
	 
	if (affected_rows != 1) /* validate affected rows */
	{
	  fprintf(stderr, " invalid affected rows by MySQL\n");
	  exit(0);
	}
	 
	//第二波赋值 
	int_data= 1000;
	strncpy(str_data, "The most popular Open Source database", STRING_SIZE);
	str_length= strlen(str_data);
	small_data= 1000;         /* smallint */
	is_null= 1;               /* reset */
	
	
	//INSERT INTO test_table(col1,col2,col3) VALUES(1000,'The most popular Open Source database',1000)
	
	
	
	
	
	
	//insert into test_table(col1,col2,col3) values(1000,'The most popular Open Source database',1000);
	 
	/* Execute the INSERT statement - 2*/
	if (mysql_stmt_execute(stmt))//第二次执行
	{
	  fprintf(stderr, " mysql_stmt_execute, 2 failed\n");
	  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
	  exit(0);
	}
	 
	/* Get the total rows affected */
	affected_rows= mysql_stmt_affected_rows(stmt);
	fprintf(stdout, " total affected rows(insert 2): %lu\n",
	                (unsigned long) affected_rows);
	 
	if (affected_rows != 1) /* validate affected rows */
	{
	  fprintf(stderr, " invalid affected rows by MySQL\n");
	  exit(0);
	}
	 
	/* Close the statement */
	if (mysql_stmt_close(stmt))
	{
	  fprintf(stderr, " failed while closing the statement\n");
	  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
	  exit(0);
	}

}

2, 查询预处理

流程图
这里写图片描述

api介绍

MYSQL_RES *mysql_stmt_param_metadata(MYSQL_STMT *stmt)

提前指定结果集的操作

//select *from dept; 查询语句的使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>

#define _USER_ "root" //用户名
#define _HOST_ "127.0.0.1" //host
#define _PASSWD_ "123"   //root 用户名密码
#define _DB_ "scott" //库名
#define _PORT_ 3306  //port


//============================stmt ======================================

#define STRING_SIZE 50
//mysql 查询语句
#define SELECT_SAMPLE "SELECT deptno, dname, loc FROM dept"


void seach_information(MYSQL *mysql){
		int 					i, count = 0;;
		MYSQL_STMT    *stmt;     //
		MYSQL_BIND    bind[3];   //条件变量
		MYSQL_RES *prepare_meta_result; //结果集
		unsigned long length[3];
		int           param_count, column_count, row_count;
		int           int_data;  //序号
		char         	str_name[STRING_SIZE]; //姓名
		char          str_loc[STRING_SIZE];
		my_bool       is_null[3];     //参数的控制
		my_ulonglong  row_unm;
	
	
	
		//===========================init start=========================
		//初始化sql预处理语句
		stmt = mysql_stmt_init(mysql);
		if (!stmt)
		{
		  fprintf(stderr, " mysql_stmt_init(), out of memory\n");
		  exit(0);
		}
		//绑定参数my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind) 
		//mysql_stmt_bind_param(stmt, bind);
		
		if (mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE)))
		{
		  fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
		  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
		  exit(0);
		}
		fprintf(stdout, " prepare, SELECT successful\n");
		fprintf(stdout, " total parameters in SELECT: %d\n", param_count);
 
 
		param_count = mysql_stmt_param_count(stmt);
		if (param_count != 0) /* validate parameter count */
		{
		  fprintf(stderr, " invalid parameter count returned by MySQL\n");
		  exit(0);
		}


		prepare_meta_result = mysql_stmt_result_metadata(stmt);
		
		if (!prepare_meta_result)
		{
		  fprintf(stderr,
		         " mysql_stmt_result_metadata(), returned no meta information\n");
		  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
		  exit(0);
		}
		
		column_count= mysql_num_fields(prepare_meta_result);
		
		fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);
 
		if (column_count != 3) /* validate column count */
		{
		  fprintf(stderr, " invalid column count returned by MySQL\n");
		  exit(0);
		}
		
		//mysql_stmt_execute(stmt); //发送占位符到mysql数据库上????
		if (mysql_stmt_execute(stmt))
		{
		  fprintf(stderr, " mysql_stmt_execute(), failed\n");
		  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
		  exit(0);
		}
		
		//初始化参数   
		memset(bind, 0, sizeof(bind));
			/* INTEGER COLUMN */
		bind[0].buffer_type= MYSQL_TYPE_LONG;
		bind[0].buffer= (char *)&int_data;
		bind[0].is_null= &is_null[0];
		bind[0].length= &length[0];
		//varchar    -- MYSQL_TYPE_VAR_STRING
		/* name COLUMN */
		bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
		bind[1].buffer= (char *)str_name;
		bind[1].buffer_length = STRING_SIZE;
		bind[1].is_null = &is_null[1];
		bind[1].length = &length[1];
		 
		/* loc COLUMN */
		bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
		bind[2].buffer= (char *)&str_loc;
		bind[2].buffer_length = STRING_SIZE;
		bind[2].is_null = &is_null[2];
		bind[2].length = &length[2];
		 
		
		
		
		//绑定数据
		mysql_stmt_bind_result(stmt, bind);
		
		mysql_stmt_store_result(stmt);//
		
		//init row
		row_count= 0;
		
		//查询的结果
		row_unm = mysql_stmt_num_rows(stmt); 
			//打印数据
		//mysql_stmt_fetch(stmt);
		//mysql_stmt_fetch(stmt);
		printf("row_unm = %ld\n", row_unm);
		for (i = 0; i < row_unm; i++)
		{
			mysql_stmt_fetch(stmt);
		  row_count++;
		  fprintf(stdout, "  row %d\n", row_count);
		 
		  /* column 1 */
		  fprintf(stdout, "   column1 (integer)  : ");
		  if (is_null[0])
					fprintf(stdout, " NULL\n");
		  else
					fprintf(stdout, " %d(%ld)\n", int_data, length[0]);
		 
		  /* column 2 */
		  fprintf(stdout, "   column2 (string)   : ");
		  if (is_null[1])
					fprintf(stdout, " NULL\n");
		  else
					fprintf(stdout, " %s(%ld)\n", str_name, length[1]);
		 
		  /* column 3 */
		  fprintf(stdout, "   column3 (string) : ");
		  if (is_null[2])
					fprintf(stdout, " NULL\n");
		  else
					fprintf(stdout, " %s(%ld)\n", str_loc, length[2]);
		 
		
		  fprintf(stdout, "\n");
		 
		  //break;
		}
		
		
		
		//释放内存
		/* Validate rows fetched */
		if (row_count != 10)
		{
		  fprintf(stderr, " MySQL failed to return all rows\n");
		  exit(0);
		}
		 
		/* Free the prepared result metadata */
		mysql_free_result(prepare_meta_result);
		 
		 
		/* Close the statement */
		mysql_stmt_close(stmt);
}


//=====================================================================


int main(int argc, char *argv[])
{
	int ret, i;
	MYSQL *mysql;
	MYSQL_RES * res;
	MYSQL_ROW row; //
	//unsigned long *lengths;
	unsigned int num_fields;
	MYSQL_FIELD *field; //字段名

	//1,mysql_init 初始化
	mysql = mysql_init(NULL);
	if (mysql == NULL) {
		printf("mysql_init error\n");
		return -1;
	}

	//2,mysql_real_connect链接
	mysql = mysql_real_connect(mysql, 
	_HOST_, 
	_USER_, 
	_PASSWD_, 
	_DB_, 
	0, 
	NULL, 
	0);

	if (mysql == NULL) {
		printf("mysql_real_connect error\n");
		return -1;
	}

	printf("connect mysql ok\n");
		//设置一下字符编码utf8
		if (mysql_set_character_set(mysql, "utf8")) {
				printf("	mysql_set_character_set error\n");
				return -1;
		}

		seach_information(mysql);
//	char sqlstr[] = "select *from emp";
//	//查询语句int mysql_query(MYSQL *mysql, const char *query) 
//	ret = mysql_query(mysql, sqlstr);
//	if (ret) {
//		printf("mysql_query error\n");
//		return -1;	
//	}
//	
//	//查询的结果集MYSQL_RES *mysql_store_result(MYSQL *mysql) 
//	res = mysql_store_result(mysql);
//
//	//MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) 
//	if ( res != NULL) {
//			// 数据的长度unsigned int mysql_num_fields(MYSQL_RES *result) 
//			num_fields = mysql_num_fields(res);
//			//返回列长unsigned long *mysql_fetch_lengths(MYSQL_RES *result) 
//			//lengths  = mysql_fetch_lengths(res);
//			printf("num_fields = [%d]\n", num_fields);
//			//字段名
//			for (i = 0; i < num_fields, field = mysql_fetch_field(res); i++) {
//						 printf(" %s\t", field->name);
//			}
//			printf("\n");
//			while (row = mysql_fetch_row(res)) {
//				
//				for (i = 0; i < num_fields; i++) {
//							printf("%s \t", row[i]);
//				}
//				printf("\n");
//			}
//				//释放结果集
// 		 mysql_free_result(res);
//	}

	
	
	//关闭mysql
	mysql_close(mysql);
     	 return 0;
}








这里写图片描述

事物的介绍

//mysql中的事务
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mysql.h"

#define SET_TRAN	"SET AUTOCOMMIT=0"  		//手动commit	————手动commit
#define UNSET_TRAN	"SET AUTOCOMMIT=1"			//自动commit

#define _HOST_ "127.0.0.1"
#define _USER_ "root"
#define _PASSWD_ "123"
#define _DBNAME_ "scott"

//设置事务为手动提交
int mysql_OperationTran(MYSQL *mysql)  			
{
	//--开启事务
	int ret = mysql_query(mysql, "start transaction");  //开启一次事务 start transaction
	if (ret != 0) {
		printf("mysql_OperationTran query start err: %s\n", mysql_error(mysql));
		return ret;
	}

	//--设置事务为手动提交
	ret = mysql_query(mysql, SET_TRAN);			//set autocommmit = 0
	if (ret != 0) {
		printf("mysql_OperationTran query set err: %s\n", mysql_error(mysql));
		return ret;
	}

	return ret;
}

//设置事务为自动提交
int mysql_AutoTran(MYSQL *mysql)
{
	//--开启事务
	int ret = mysql_query(mysql, "start transaction");  
	if (ret != 0) {
		printf("mysql_AutoTran query start err: %s\n", mysql_error(mysql));
		return ret;
	}

	//--设置事务为自动提交
	ret = mysql_query(mysql, UNSET_TRAN);  //"set autocommit = 1"
	if (ret != 0) {
		printf("mysql_AutoTran query set err: %s\n", mysql_error(mysql));
		return ret;
	}

	return ret;		
}

//执行commit,手动提交事务
int mysql_Commit(MYSQL *mysql)
{
	int ret = mysql_query(mysql, "COMMIT"); //提交
	if (ret != 0) {
		printf("commit err: %s\n", mysql_error(mysql));
		return ret;
	}
	return ret;
}

//执行rollback,回滚事务		
int mysql_Rollback(MYSQL *mysql)
{
	int ret = mysql_query(mysql, "ROLLBACK");
	if (ret != 0) {
		printf("rollback err: %s\n", mysql_error(mysql));
		return ret;
	}
	return ret;
	
}

#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
#define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\
                                                 col2 VARCHAR(10),\
                                                 col3 VARCHAR(10))"
                                                                                       
#define sql01 "INSERT INTO test_table(col1,col2,col3) VALUES(10, 'AAA', 'A1')"
#define sql02 "INSERT INTO test_table(col1,col2,col3) VALUES(20, 'BBB', 'B2')"
#define sql03 "INSERT INTO test_table(col1,col2,col3) VALUES(30, 'CCC', 'C3')"
#define sql04 "INSERT INTO test_table(col1,col2,col3) VALUES(40, 'DDD', 'D4')"

int main(void)
{
	int ret = 0;

	MYSQL *mysql = mysql_init(NULL);
	
	mysql = mysql_real_connect(mysql, _HOST_, _USER_, _PASSWD_, _DBNAME_, 0, NULL, 0);
	if (mysql == NULL) {
		ret = mysql_errno(mysql);
		printf("func mysql_real_connect() err:%d\n", ret);
		return ret;
	} 	
	printf(" --- connect ok......\n");	
	//执行删除表
	if (mysql_query(mysql, DROP_SAMPLE_TABLE)) {
	  fprintf(stderr, " DROP TABLE failed\n");
	  fprintf(stderr, " %s\n", mysql_error(mysql));
	  exit(0);
	}
	//执行创建表
	if (mysql_query(mysql, CREATE_SAMPLE_TABLE)) {
	  fprintf(stderr, " CREATE TABLE failed\n");
	  fprintf(stderr, " %s\n", mysql_error(mysql));
	  exit(0);
	}	
	
	ret = mysql_OperationTran(mysql); 	//开启事务,并修改事务属性为手动commit 
	if (ret != 0) {
		printf("mysql_OperationTran() err:%d\n", ret);
		return ret;
	}
	
	ret = mysql_query(mysql, sql01);	//向表中插入第一行数据 ‘AAA’
	if (ret != 0) {
		printf("mysql_query() err:%d\n", ret);
		return ret;
	}
	
	ret = mysql_query(mysql, sql02);	//向表中插入第二行数据 ‘BBB’
	if (ret != 0) {
		printf("mysql_query() err:%d\n", ret);
		return ret;
	}
	
	ret = mysql_Commit(mysql); 			//手动提交事务
	if (ret != 0) {
		printf("mysql_Commit() err:%d\n", ret);
		return ret;
	}
	//AAA BBB  进去了。
	
#if 1
	ret = mysql_AutoTran(mysql); 		// =再次= 修改事务属性为【自动】commit
	if (ret != 0) {
		printf("mysql_OperationTran() err:%d\n", ret);
		return ret;
	}
#else 
	ret = mysql_OperationTran(mysql); 	// =再次= 修改事务属性为【手动】commit
	if (ret != 0) {
		printf("mysql_OperationTran() err:%d\n", ret);
		return ret;
	}
#endif

	ret = mysql_query(mysql, sql03);	//向表中插入第三行数据 ‘CCC’
	if (ret != 0) {
		printf("mysql_query() err:%d\n", ret);
		return ret;
	}
	
	ret = mysql_query(mysql, sql04);	//向表中插入第四行数据 ‘DDD’
	if (ret != 0) {
		printf("mysql_query() err:%d\n", ret);
		return ret;
	}
	
	ret = mysql_Rollback(mysql);		//直接rollback操作
	if (ret != 0) {
		printf("mysql_Rollback() err:%d\n", ret);
		return ret;
	}
	
	//rollback操作是否能回退掉CCC、DDD的值,取决于事务属性。
	
	mysql_close(mysql);
	
	return 0;	
}





  • 20
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值