MYSQL数据库编程

来源:互联网 发布:java字符串拼接加空格 编辑:程序博客网 时间:2024/06/05 20:54

连接MYSQL数据库的c语言函数库包含在mysqlclient库中,头文件为mysql.h。连接MYSQL服务器时,应用程序应使用下列步骤进行操作。
(1)通过调用mysql_library_init()函数初始化MYSQL库。库可以是mysqlclient c客户端库,或mysqld嵌入式服务器库,具体情况取决于应用程序编译时是否与-libmysqlclient或-libmysqld标志链接
(2)通过调用mysql_init()函数初始化连接处理程序,并通过调用mysql_real_connect()函数连接到服务器
(3)通过调用mysql_close()函数关闭与MYSQL服务器的连接
(4)通过调用mysql_library_end()函数结束MYSQL库的使用
调用mysql_library_init()和mysql_library_end()的目的在于为MYSQL库提供恰当的初始化和结束处理。对于与客户端库链接的应用程序,它们提供了改进的内存管理功能。原型为:

int mysql_library_init(int argc,char **argv,char **groups);void mysql_library_end(void);

使用mysql_init初始化连接句柄,原型:

MYSQL *mysql_init(MYSQL *);

如果传递一个空指针给mysql_init这个函数,它会返回一个指向新分配的连接句柄结构的指针;如果传递一个已有的MYSQL结构指针,则它将被重新初始化。如果出错,返回NULL。
初始化成功后,则使用mysql_real_connect来创建一个实际的连接

MYSQL *mysql_real_connect(    MYSQL *connection,    const char *server_host,    const char *sql_user_name,       const char *sql_password,    const char *db_name,    unsigned int port_number,    const char *unix_socket_name,    unsigned int flags);

connection必须是已经初始化的连接句柄结构,server_host可以是主机名,也可以是IP地址,如果仅仅连接到本机,可以使用 localhost来优化连接类型。port_number和unix_socket_name应该分别为0和NULL,除非改变了MYSQL安装的默认设置。如果无法连接,返回NULL。
完成连接后,在程序正常退出前,应该使用mysql_close关闭这个连接句柄。

void mysql_close(MYSQL *connection);

ps:编译时可能遇到的问题
①错误:mysql.h:没有那个文件或目录。提示没有找到mysql.h,产生这个错误的原因是没有mysql.h文件,它在mysql-devel包中,需要安装这个包
②cannot find -lmysqlclient。提示没有找到mysqlclient链接库,man gcc发现可以在后面用-L指定搜索位置,链接库在/usr/lib/mysql目录中。
编译:gcc -I/usr/include/mysql connect.c -lmysqlclient -L/usr/lib/mysql -o connect
(-I的含义是在指定位置搜索头文件,参见man gcc;-L的含义是在指定位置搜索链接库,参见man gcc)

操作数据库

进入数据库中之后,就可以开始对数据库进行读写操作了,数据库的主要操作包括select, insert, update, delete四种。

sql语句的嵌入

执行SQL语句的主要API函数是:

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

接受已经建立的连接结构指针和文本字符串形式的有效SQL语句(句末不用分号),成功返回0。
还有一个比较重要的函数,mysql_affected_rows(),它返回无符号类型。当使用printf时,推荐使用%lu格式将其转换为无符号长整型。此函数返回受之前执行的update,delete,insert等查询影响的行数。

my_ulonglong mysql_affected_rows(MYSQL *connection);

MySQL返回操作修改的行数,但其他许多数据库将仅仅因为记录匹配where字句而把它视为已经更新过。mysql_affected_row返回的是真正受到影响或者说是被改变的行数,而不仅仅是匹配where字句的行数。
通常对于mysql_affected_rows()函数,返回值0表示没有行受到影响,正数则是实际的结果,一般表示受语句影响的行数。

select语句的使用

select语句是SQL语句中使用最频繁的操作。
一个完整的提取数据过程应该包含以下四个步骤:执行查询,提取数据,处理数据,清理。
使用mysql_query来发送SQL语句,使用mysql_store_result或者mysql_use_result来提取数据。然后使用 mysql_fetch_row调用来处理数据,最后,使用mysql_free_result来释放查询占用的内存资源。
mysql_use_result和mysql_store_result都是返回一个指向结果集结构(result set structure)的指针,如果失败则返回NULL。区别在于store将查询到的数据库中的结果直接放在这个结果集中,而use则不直接将最终数据库 的数据结果放在这个结果集中。store其实就是把数据直接读到本地内存中,因此它比较适合数据量较小的查询。use则类似于一种流的操作,并不是一次就 返回所有的结果。因此,对于这个结果集,必须反复调用mysql_fetch_row直到提取所有的数据。
1)一次获取所有的数据:

MYSQL_RES *mysql_store_result(MYSQL *connection);

在成功调用mysql_query之后使用此函数,将立即保存在客户端中返回的所有数据,并将指向此结果集的指针返回。如果失败则返回NULL。
成功之后,可以用mysql_num_rows来得到返回记录的数目,一般应该是个正数,若没有返回行匹配,则返回0.

my_ulonglong mysql_num_rows(MYSQL_RES *result);

现在得到来数据,可使用mysql_fetch_row来处理它,也可以使用mysql_data_seek,mysql_row_seek和mysql_row_tell在数据集中来回移动。

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

此函数从上面得到的结果集中提取一行,并把它放在一个行结构中。当数据用完或者出错时返回NULL。

void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);

此函数允许结构集当前指针的跳转,设置会被下一个mysql_fetch_row操作返回的行。offset是行号,在0到总行数减1的范围内。传递0,则返回初始位置。

MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);

此函数返回结果集的当前位置。不能把它用于mysql_data_seek。
完成来对数据的所有操作之后,必须调用mysql_free_result来让MYSQL数据库完成善后处理。

void mysql_free_result(MYSQL_RES *result);

2)一次提取一行数据
建议使用这种提取数据的方式。它能取得更好的网络负载平衡,以及减少大数据集可能造成的存储过载。但是它也增加来时延,并且在特殊的情况下,比如网络链接在操作中途失败时,可能会得到不完整的数据甚至造成混乱。
此时依靠mysql_use_result:

MYSQL_RES *mysql_use_result(MYSQL *connection);

与store一样,出错返回NULL,成功则返回指向结果集对象的指针。

update,insert,和delete语句的使用

update, insert和delete这三个操作是不用返回任何数据的语句,他们都是使用mysql_query来执行语句。

int res = mysql_query(&my_connection, "SQL语句");if(!res){    printf("operation success\naffected %lu rows\n", (unsigned long)mysql_affected_row (&my_connection));}else{    fprintf(stderr,"failed error: %d: %s", mysql_errno(&my_connection), mysql_error(&my_connection));}
0 0
原创粉丝点击