• linux程序设计——运行SQL语句(第八章)


    8.3    使用C语言訪问MySQL数据

    8.3.3 运行SQL语句

    运行SQL语句的主要API函数被恰当的命名为:
    int mysql_query(MYSQL *connection, const char *query);
    这个例程接受连接结构指针和文本字符串形式的有效SQL语句,假设成功,它返回0.

    1.不返回数据的SQL语句

    为简单起见,先看一些不返回不论什么数据的SQL语句:UPDATE,DELETE和INSERT.
    以下的函数用于检查受查询影响的行数:
    my_ulonglong mysql_affected_rows(MYSQL *connection);
    这个函数的返回值类型非常不常见,它使用无符号类型是出于移植性的考虑.当使用printf时,最好使用%lu格式将其转换为无符号长整形.这个函数返回受之前运行的UPDATE,DELETE和INSERT查询影响的函数.MySQL返回的是被一个更新操作改动的行数.
    通常对于mysql_系列函数,返回值0表示没有行受到影响,正数则是实际的结果,一般表示受影响的行数.
    编敲代码insert1.c,尝试在表中插入一个新行.
    mysql_affected_rows返回实际对数据进行的改动或者插入的行数.此外当从数据库中删除数据时,假设使用WHERE子句删除数据,那么mysql_affected_rows将返回删除的行数.但假设在DELETE语句中卖没有WHERE子句,那么表中的全部行都会被删除,可是由程序返回的受影响的行数却为0.这是由于MySQL优化了删除全部行的操作,它并非运行很多个单行删除操作.

    2.发现插入的内容

    auto_increment类型由MySQL自己主动分配ID,这一特性很实用,特别是当有很多用户的时候.
    CREATE TABLE children(
            childno int auto_increment NULL PRIMARY KEY,
            fname varchar(30),
            age int
    );
    MySQL提供函数LAST_INSERT_ID()给出了auto_increment列的值.
    不管何时MySQL向auto_increment列中插入数据,MySQL都会基于每一个用户对最后分配的值进行跟踪.用户程序能够通过SELECT专用函数LAST_INSERT_ID()来发现该值,这个函数的作用有点像表中的虚拟列.
    编敲代码insert2.c

    3.返回数据的语句

    SQL最常见的使用方法当然是提取数据而不是插入或更新数据.数据是使用SELECT语句提取的.
    MySQL也支持使用SQL语句SHOW,DESCRIBE和EXPLAIN来返回结果,临时不涉及它们.
    在C应用程序中提取数据一般须要以下4个步骤:
    运行查询
    提取数据
    处理数据
    必要的清理工作

    就像之前的INSERT和DELETE语句一样,将使用mysql_query来发送SQL语句运行查询,然后使用mysql_store_result或mysql_use_result来提取数据,详细使用哪个函数取决于想怎样提取数据.接着将使用一系列mysql_fetch_row调用来处理数据,最后使用mysql_free_result释放查询占用的内存资源.
    mysql_use_result和mysql_store_result的差别主要在于,是想一次返回一行数据,还是一次返回全部的结果.当语句结果集较小时,后者比較合适.
    一次提取全部数据的函数
    能够使用mysql_store_result在一次调用中从SELECT中提取全部数据:
    MYSQL_RES *mysql_store_result(MYSQL *connection);
    显然,须要在成功调用mysql_query之后使用此函数.这个函数将立马保存从client中返回的数据.它返回一个指向结果集结构的指针,假设失败返回NULL.
    my_ulonglong mysql_num_rows(MYSQL_RES *result);
    这个函数接受由mysql_store_result返回的结果,并返回的结果结构,并返回结果集中的行数.假设mysql_store_result调用成功,mysql_num_rows将始终都是成功的.
    假设使用的是一个特别庞大的数据集,那么最好提取小一些,更easy管理的信息块,由于这将更快地将控制权返回给应用程序,而且不会占用大量的网络资源.
    使用mysql_fetch_row来处理它,也能够使用mysql_data_seek,mysql_row_seek和mysql_row_tell在数据集中来回移动.
    1.mysql_fetch_row:这个函数从使用mysql_store_result得到的结果中提取一行,并把它放到一个行结构中.当数据用完或错误发生时返回NULL.
    MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
    2.mysql_data_seek:这个函数用来在结果集中进行跳转,设置将被下一个mysql_fetch_row操作返回的行.參数offset的值是一个行号,它必须在0到结果集总行数减1的返回内.传递0将会导致下一个mysql_fetch_row调用返回结果集中的第一行.
    void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
    3.mysql_row_tell:这个函数返回一个偏移值,它用来表示结果集中的当前位置.它不是行号,不能将它用于mysql_data_seek.
    MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);
    可是能够这样使用它的返回值:
    MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);
    这将在结果集中移动当前位置,并返回之前的值.
    这对函数对于结果集中的已知点之间的移动很实用.可是不要混淆由row_tell和row_seek使用的偏移量和data_seek使用的行号.
    4.完毕了对数据的全部操作之后,必须明白地调用mysql_free_result来让MySQL库完毕善后处理.
    提取数据
    编敲代码select1.c提取全部年龄大于5的记录
    #include <stdlib.h>
    #include <stdio.h>
    #include "mysql.h"
    
    int main(int argc, char *argv[]){
    	int res;
    	MYSQL my_connection;
    	MYSQL_RES *res_ptr;
    	MYSQL_ROW sqlrow;
    
    	mysql_init(&my_connection);
    	//初始化连接句柄,返回一个指向新分配的连接句柄的指针,仅仅是分配和初始化了一个结构
    	if (mysql_real_connect(&my_connection, "localhost", "rick","secret", "foo", 0, NULL, 0)){
    		//mysql_real_connect向一个连接提供參数,指针connection指向已经被mysql_init初始化过的结构
    		printf("Connection success
    ");
    		res = mysql_query(&my_connection, "SELECT childno, fname, age FROM children WHERE age > 5");
    		//mysql_query參数为结构指针和文本字符串形式的SQL语句,假设成功则运行字符串表示的SQL语句,返回0
    		if (res){
    			printf("SELECT error: %s
    ", mysql_error(&my_connection));
    		}else{
    			res_ptr = mysql_store_result(&my_connection);
    			//mysql_store_result在一次调用中从SELECT中提取全部数据,返回指向结果集结构的指针
    			if (res_ptr){
    				printf("Retrieved %lu rows
    ", (unsigned long)mysql_num_rows(res_ptr));
    				//mysql_num_rows得到返回记录的数目,接受由mysql_store_result返回的结果结构指针
    				while((sqlrow = mysql_fetch_row(res_ptr))){
    					//mysql_fetch_row从mysql_store_result的结果结构中提取一行
    					printf("Fetched data...
    ");
    				}
    				if (mysql_errno(&my_connection)){
    					//mysql_errno返回错误码,非零
    					fprintf(stderr, "Retrieve error: %s
    ", mysql_error(&my_connection));
    					//mysql_error返回错误的文本信息
    				}
    				mysql_free_result(res_ptr);
    				//mysql_free_result释放查询占用的内存资源
    			}
    		}
    		mysql_close(&my_connection);
    		//关闭连接
    	}
    	else{
    		fprintf(stderr, "Connection failed
    ");
    		if (mysql_errno(&my_connection)){
    			fprintf(stderr, "Connection error %d: %s
    ", mysql_errno(&my_connection),
                                      mysql_error(&my_connection));
    		}
    	}
    	return EXIT_SUCCESS;
    }


  • 相关阅读:
    SolidWorks 2-12 拉伸特征03
    css记
    微信小程序的wxss好难啊,记录我的搞笑界面
    redis的学习使用,第二章
    本周学习Task-Rocketmq
    springcloud-ribbon的使用
    eclipse上使用svn更新代码
    新入职感觉
    在windows里面的数据库里面存emoji表情
    centos7,关闭mysql。出现mysql启动不了的情况
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7142628.html
Copyright © 2020-2023  润新知