目录:html
1、解决小的问题;mysql
其实写这个程序真的很简单,十多分钟的事情,只是之前没在Linux下用纯C连过Mysql,想试一下,居然搞了一成天,并且不是因为编码自己,是由于其余的一些周边问题,因此颇有必要作一下笔记。api
C语言针对MySql函数的帮助怎么查找:这些东西在MySql提供的帮助文档里都是有的,索引是C API。能够本身去下载chm格式的帮助文档,我的以为这种文档比较好用,也能够去官网自行决定下载其余类型的帮助文档:http://dev.mysql.com/doc/,或者在线查找:https://dev.mysql.com/doc/refman/5.1/zh/apis.html。用高级语言编程其实就是学会使用帮助文档并付诸实践的过程。ide
关于这点,须要作点准备工做:函数
一、安装mysql:
sudo apt-get install mysql-server
二、安装库文件和头文件:
sudo apt-get install libmysqlclient-devfetch
也能够本身去官网下载对应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/中。spa
这个问题其实不是什么大问题,是头文件引用的时候相对路径不对,若是编译器提示你某个头文件不存在,可是你在那个文件夹里查看又发现这个头文件实际上是存在的。
好比说题述问题,咱们在Linux下用C连mysql的时候要包含头文件:#include<mysql/mysql.h>,编译的时候编译器提示错误,<mysql/plugin_auth_common.h>不存在?
其实咱们能够找到的是/usr/include/mysql/mysql/plugin_auth_common.h,而后,把该头文件复制到父级目录便可,编译器就能正确找到这个头文件。
其实都是相对路径的问题。
好比写好的文件为main.c,转到文件所在目录(cd命令),而后进行编译,并尝试执行:
gcc -o conn main.c -l mysqlclient
chmod +x conn
./conn
若是不加-lmysqlclient 连接选项的话,通常会提示undefined reference to `mysql_init' ,实际上是由于init是最开始被调用的函数,因此它就最早提示这个而已。
若是想要调试的话能够用gdb,不过我本身用得都不是很熟,因此就很少说了。
Project->Properties->Settings->Cross GCC Compiler->Includes->Include paths(-I),包含以下两个路径:
/usr/include/mysql和/usr/lib/mysql,如图:
而后在Cross GCC Linker->Libraries中的Libraries(-I)中添加link:mysqlclient,在Library search path(-L)中添加路径/usr/lib/mysql,如图:
原本一开始我是在QtCreator里面写的,编译的时候发现不知道哪里加-l mysqlclient这个连接选项,没办法,一点都不会用qmake,也不会用cmake,而后就想用Eclipse来写,而后又发现Eclipse没办法识别mysql的那些头文件,因而又折腾了一阵子。写倒不是问题,主要是这些IDE调试的时候比较方便(其实也主要是由于不太会用GDB),唉,各类碰壁。
这个不相关的问题是怎么来的?其实就是由于编译器提示某个头文件找不到,我觉得是当前用户没权限去访问/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 --须要根用户权限
重启,进入系统,恢复正常。因此说,根目录的东西不要去乱搞。
其实这个最没什么好说的,不过最后仍是写了个Demo 。
开始建表以下:
id为INT,主键,AUTO_INCREMENT,text为varchar(15)。
程序源码:
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!\n"); 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\n",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\n",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!\n",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\n",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\n",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\t",i,mysql_field[i].name); 50 } 51 printf("\n"); 52 size_t i_temp=0; 53 while((mysql_row=mysql_fetch_row(mysql_res))) 54 { 55 printf("The ID %d is %s\n",++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\n",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\n",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\n",mysql_error(conn),mysql_stmt_error(mysql_stmt)); 70 exit(0); 71 } 72 fprintf(stdout,"Init and preparation succeeded!\n"); 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\n"); 84 fprintf(stderr, " %s\n", mysql_stmt_error(mysql_stmt)); 85 exit(0); 86 } 87 88 if(mysql_stmt_execute(mysql_stmt)) 89 { 90 fprintf(stderr,"Execution failed:%s\n",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\n", 95 (unsigned long) affected_rows); 96 97 if (mysql_stmt_close(mysql_stmt)) 98 { 99 fprintf(stderr, " failed while closing the statement\n"); 100 fprintf(stderr, " %s\n", mysql_stmt_error(mysql_stmt)); 101 exit(0); 102 } 103 //Insert opration success//////////////////////////////////////////////////////////// 104 mysql_close(conn); 105 printf("End of the file\n"); 106 }
执行若干次之后结果以下:
写完,睡觉。