Linux下C连接MySql数据库

摘要:
如何找到C语言对MySql函数的帮助:这些内容在MySql提供的帮助文档中提供,索引为CAPI。如果它是一个tar压缩包,请将其解压缩,将include文件夹复制到/usr/include/mysql/,然后将lib文件夹复制到/usr/lib/mysql/。例如,对于所描述的问题,当我们在Linux下使用C连接MySQL时,我们需要包含头文件:#include 。编译时,编译器会提示一个错误, 不存在?

目录:

一、解决小的问题;

二、大问题,如果你不小心把/usr/lib的所属用户改了导致sudo命令用不了:

三、C连接MySql编程本身:

其实写这个程序真的很简单,十多分钟的事情,只是以前没在Linux下用纯C连过Mysql,想试一下,竟然搞了一整天,而且不是由于编码本身,是因为其他的一些周边问题,所以很有必要做一下笔记。

一、解决小的问题:

1、怎么自己去学着编写?

C语言针对MySql函数的帮助怎么查找:这些东西在MySql提供的帮助文档里都是有的,索引是C API。可以自己去下载chm格式的帮助文档,个人觉得这种文档比较好用,也可以去官网自行决定下载其他类型的帮助文档:http://dev.mysql.com/doc/,或者在线查找:https://dev.mysql.com/doc/refman/5.1/zh/apis.html。用高级语言编程其实就是学会使用帮助文档并付诸实践的过程。

2、在编写之前请确定自己有相关的头文件和库文件

关于这点,需要做点准备工作:

1、安装mysql:
sudo apt-get install mysql-server
2、安装库文件和头文件:
sudo apt-get install libmysqlclient-dev

也可以自己去官网下载对应mysql的安装包进行安装:http://dev.mysql.com/downloads/mysql/,单独下载connector的rpm或者tar包:http://dev.mysql.com/downloads/connector/。

如果是tar压缩包,解压出来,把include文件夹复制(cp命令,需root权限)到/usr/include/mysql/中,然后将lib文件夹复制到/usr/lib/mysql/中。

3、偶遇奇怪问题 fatal error: mysql/plugin_auth_common.h

这个问题其实不是什么大问题,是头文件引用的时候相对路径不对,如果编译器提示你某个头文件不存在,但是你在那个文件夹里查看又发现这个头文件其实是存在的。

比如说题述问题,我们在Linux下用C连mysql的时候要包含头文件:#include<mysql/mysql.h>,编译的时候编译器提示错误,<mysql/plugin_auth_common.h>不存在?

其实我们可以找到的是/usr/include/mysql/mysql/plugin_auth_common.h,然后,把该头文件复制到父级目录即可,编译器就能正确找到这个头文件。

其实都是相对路径的问题。

4、怎么用GCC命令正确编译:

比如写好的文件为main.c,转到文件所在目录(cd命令),然后进行编译,并尝试执行:

gcc -o conn main.c -l mysqlclient

chmod +x conn

./conn

如果不加-lmysqlclient 链接选项的话,一般会提示undefined reference to `mysql_init' ,其实是因为init是最开始被调用的函数,所以它就最先提示这个而已。

如果想要调试的话可以用gdb,不过我自己用得都不是很熟,所以就不多说了。

5、Eclipse(Kepler-Cpp)构建针对MySql的开发环境:

Project->Properties->Settings->Cross GCC Compiler->Includes->Include paths(-I),包含如下两个路径:

/usr/include/mysql和/usr/lib/mysql,如图:

Linux下C连接MySql数据库第1张

然后在Cross GCC Linker->Libraries中的Libraries(-I)中添加link:mysqlclient,在Library search path(-L)中添加路径/usr/lib/mysql,如图:

Linux下C连接MySql数据库第2张

本来一开始我是在QtCreator里面写的,编译的时候发现不知道哪里加-l mysqlclient这个链接选项,没办法,一点都不会用qmake,也不会用cmake,然后就想用Eclipse来写,然后又发现Eclipse没办法识别mysql的那些头文件,于是又折腾了一阵子。写倒不是问题,主要是这些IDE调试的时候比较方便(其实也主要是因为不太会用GDB),唉,各种碰壁。

二、大问题,如果你不小心把/usr/lib的所属用户改了导致sudo命令用不了:

这个不相关的问题是怎么来的?其实就是因为编译器提示某个头文件找不到,我以为是当前用户没权限去访问/usr/lib/mysql文件夹里面的库文件(这个文件夹是cp过去的,当时我也不清楚它的权限状态)。于是我把/usr/lib/mysql文件夹的所属用户改成了nerohwang,而且还重启了计算机,悲剧了。

重新进入系统以后,每次使用sudo命令的时候都提示,/usr/lib下的某文件出错,该文件的所属用户必须是UID为0的用户(其实就是root用户)。

可想而知,一个使用Linux系统的人无法通过sudo来获取root权限是什么感觉,感觉就是什么事情都做不了。没错,可以通过su命令来变成root用户,但是我是没有对root指定密码的,所以没有办法,甚至一度想过对系统进行重装(自杀)。

后来想到去Windows系统下用软碟通(UltrISO)写一个Ubuntu系统到U盘里,然后U盘启动以后选试用Ubuntu而不是安装。进到试用系统后,获取根用户权限(竟然不用密码),然后将原系统的那些文件权限恢复:

sudo su

cd /你平时用的Linux根目录的路径(桌面系统会帮你把这个系统挂载上,你可以点选以后通过右键--属性选项查看) 

chown -R root:root /usr/lib

chown -R root:root /usr/include

上面所说的,桌面系统会帮你挂载那个分区,当然也可以自行挂载:

fdisk -l       -------查看分区情况,比如说我们发现那个系统分区在/dev/sda1上:

mount /dev/sda1 /mnt/DirName        --需要根用户权限

重启,进入系统,恢复正常。所以说,根目录的东西不要去乱搞。

三、C连接MySql编程本身:

其实这个最没什么好说的,不过最后还是写了个Demo 。

开始建表如下:

Linux下C连接MySql数据库第3张

id为INT,主键,AUTO_INCREMENT,text为varchar(15)。

程序源码:

Linux下C连接MySql数据库第4张Linux下C连接MySql数据库第5张
  1 /*Author:nerohwang
  2 Date:2014/3/7*/
  3 #include <stdio.h>
  4 #include<stdlib.h>
  5 #include<mysql/mysql.h>
  6 #include<string.h>
  7 #define INSERT_QUERY "INSERT INTO tblTest(text) values(?)"
  8 void main(void)
  9 {
 10     size_t break_point = 0;
 11     printf("Hello World!
");
 12     MYSQL *conn;
 13     MYSQL mysql;
 14     MYSQL_RES *mysql_res;
 15     MYSQL_ROW *mysql_row;
 16     MYSQL_FIELD *mysql_field;
 17     MYSQL_STMT *mysql_stmt;
 18     unsigned int num_fields;
 19     const char * server = "localhost";
 20     const char *user = "root";
 21     const char *passwd = "cc527888";
 22     const char *dataBase = "dbTest";
 23     const char *query_select = "select * from tblTest";
 24     conn = mysql_init(NULL);
 25     if(!mysql_real_connect(conn,server,user,passwd,dataBase,0,NULL,0))
 26     {
 27         fprintf(stdout,"Error connecting to Mysql: %s
",mysql_error(conn));
 28     }
 29     int t = mysql_query(conn,query_select);
 30     if(t)   //t=0 means correct
 31     {
 32         fprintf(stderr,"Query error occurs:%s
",mysql_error(conn));
 33     }
 34 
 35     mysql_res = mysql_use_result(conn);
 36       if(mysql_res == NULL)
 37       {
 38           fprintf(stderr,"Query error occurs: %s!
",mysql_error(conn));
 39       }
 40       num_fields = mysql_num_fields(mysql_res);
 41       unsigned int num_rows = mysql_num_rows(mysql_res);
 42       printf("There're %d columns in the table tblTest
",num_fields);
 43       //The code below won't return correct result until all rows in result_Set have been retieved
 44       printf("There're %d rows affected in the table tblTest
",num_rows);
 45       mysql_field = mysql_fetch_fields(mysql_res);
 46       unsigned int i=0;
 47       for(i=0; i< num_fields; i++)
 48       {
 49           printf("Field %u is %s	",i,mysql_field[i].name);
 50       }
 51       printf("
");
 52       size_t i_temp=0;
 53       while((mysql_row=mysql_fetch_row(mysql_res)))
 54       {
 55           printf("The ID %d is %s
",++i_temp,mysql_row[1]);
 56       }
 57       num_rows = mysql_num_rows(mysql_res);
 58       printf("There're %d rows affected in the table tblTest
",num_rows); //Now ,it's correct
 59 
 60 
 61     //Insert operation//////////////////////////////////////////////////////////////////////////
 62     if(!(mysql_stmt=mysql_stmt_init(conn)))
 63     {
 64         fprintf(stderr,"Statement initialization failed: %s
",mysql_stmt_error(mysql_stmt));
 65         exit(0);
 66     }
 67     if(mysql_stmt_prepare(mysql_stmt,INSERT_QUERY,strlen(INSERT_QUERY))) //0 means correct
 68     {
 69         fprintf(stderr,"Statament preparation failed:%s and %s
",mysql_error(conn),mysql_stmt_error(mysql_stmt));
 70         exit(0);
 71     }
 72     fprintf(stdout,"Init and preparation succeeded!
");
 73     MYSQL_BIND bind[1];
 74     memset(bind, 0, sizeof(bind));
 75     char *ch = "test_in";
 76     int lengthCH = strlen(ch);
 77     bind[0].buffer_type = MYSQL_TYPE_VARCHAR;
 78     bind[0].buffer = ch;
 79     bind[0].is_null = 0;
 80     bind[0].length = &lengthCH;
 81     if (mysql_stmt_bind_param(mysql_stmt, bind))
 82     {
 83       fprintf(stderr, " mysql_stmt_bind_param() failed
");
 84       fprintf(stderr, " %s
", mysql_stmt_error(mysql_stmt));
 85       exit(0);
 86     }
 87 
 88     if(mysql_stmt_execute(mysql_stmt))
 89     {
 90         fprintf(stderr,"Execution failed:%s
",mysql_stmt_error(mysql_stmt));
 91         exit(0);
 92     }
 93     my_ulonglong affected_rows= mysql_stmt_affected_rows(mysql_stmt);
 94     fprintf(stdout, " total affected rows(insert 1): %l
",
 95                     (unsigned long) affected_rows);
 96 
 97     if (mysql_stmt_close(mysql_stmt))
 98     {
 99         fprintf(stderr, " failed while closing the statement
");
100         fprintf(stderr, " %s
", mysql_stmt_error(mysql_stmt));
101         exit(0);
102     }
103    //Insert opration success////////////////////////////////////////////////////////////
104     mysql_close(conn);
105     printf("End of the file
");
106 }
C_Mysql

执行若干次以后结果如下:

Linux下C连接MySql数据库第6张

 写完,睡觉。

免责声明:文章转载自《Linux下C连接MySql数据库》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇iOS设置启动页后的广告页[转]git图解(3):分支操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

剖析 Linux hypervisor

hypervisor 之于操作系统类似于操作系统之于进程。它们为执行提供独立的虚拟硬件平台,而虚拟硬件平台反过来又提供对底层机器的虚拟的完整访问。但并不是所有 hypervisor 都是一样的,这是件好事,因为 Linux 就是以灵活性和选择性著称。本文首先简要介绍虚拟化和 hypervisor,然后探索两个基于 Linux 的 hypervisor。 虚...

Centos7中在线/离线安装DockerCE最新版

Docker在Centos7在线/离线安装 一、在线安装 1、检查系统是否支持,因为Docker 要求 CentOS 系统的内核版本高于 3.10 uname -r 2、确保 yum 包更新到最新 yum update 3、卸载旧版本 yum remove docker docker-common docker-selinux docker-engine...

MYSQL的常用命令和增删改查语句和数据类型

连接命令:mysql -h[主机地址] -u[用户名] -p[用户密码]   创建数据库:create database [库名]   显示所有数据库: show databases;   打开数据库:use [库名]   当前选择的库状态:SELECT DATABASE();   创建数据表:CREATE TABLE [表名]([字段名] [字段类型]...

Centos 6/Redhat 6:远程图形桌面: tigervnc

step 0:【Centos 6/Redhat 6】安装桌面环境。 step 1:安装tigervnc-server step 2:配置 /etc/sysconfig/vncservers     样例: VNCSERVERS="1:root 2:oracle 3:mysql" VNCSERVERARGS[1]="-geometry 1024x768"...

Linux内核笔记:epoll实现原理(一)

一、说明 针对的内核版本为4.4.10。 本文只是我自己看源码的简单笔记,如果想了解epoll的实现,强烈推荐下面的文章: The Implementation of epoll(1) The Implementation of epoll(2) The Implementation of epoll(3) The Implementation of ep...

Linux系统下安装python3.7.3环境

这里用到的Linux系统是centos7系统,centos7是自带py的但是py的2.7.5版本                         连接服务器的使用的是SSH Secure shell 1.首先安装依赖包1)安装gcc编译器   gcc编译器有些系统版本已经默认安装了,可以通过 gcc --version进行查看              安...