首页 > 代码库 > 数据库编程5 MySQL C API 开发

数据库编程5 MySQL C API 开发

本文谢绝转载原文来自http://990487026.blog.51cto.com

数据库编程5 MySQL C API 开发
	MySQL官方文档:
	MySQL  环境搭建
		ubuntu搭建MySQL开发环境:
		MySQL服务命令
		检查MySQL运行状态:
	MySQL SQL
		登陆测试
		创建一个数据库
		显示数据库创建过程:
		创建一个使用UTF8字符集的数据库
		创建一个使用UTF8字符集的数据库,带校对规则
		把数据库修改成UTF8字符集
		选择数据库,创建表:
		查表结构:
		mysql中的数据类型
		创建员工表:
		修改表名:
		删除表:
		插入中文:
		数据环境搭建:
			求学生总分:
			增加一个字段:
			update表 where and
			update表 where between and
			求各个班级的平均分:
		Oracle分组机制很好,MySQL不伦不类的显示:
		日期时间函数
			获取当前日期和时间
			获取当前日期和时间,简写方式
			获取当前日期
			获取当前时间
			获取当前时间戳
			获取指定时间的日期:
			日期加减:
			年加减:
		创建班级表:
		插入数据:
		多表查询,环境搭建,模拟Oracle scott用户的表
			验证环境搭建结果:
			多表查询,等值连接,显示员工编号,姓名,薪水,职位
			多表查询,where 不等值连接,显示员工编号,姓名,薪水,职位,薪水级别
			多表查询,between and 不等值连接,显示员工编号,姓名,薪水,职位,薪水级别
			多表查询,分组, 按部门统计员工人数:显示部门号,部门名称,部门人数
			多表查询,分组, 外连接,按部门统计员工人数,并显示40号部门信息
			显示 不是管理者的信息:左外连接,滤空
		MySQL 乱码的原因:	
		MySQL乱码话题:	
		MySQL乱码分析:	
		
		
	MySQL C API 编程
		我的系统环境:
			mysql头文件:
			mysql动态库文件:
		MySQL C API Hello World程序
		MySQL C API 的select 程序
		MySQL C API 显示数据,自适应字段的个数:
		MySQL C API 增加表头的输出:
		MySQL C API 中文问题,设置语言集
		MySQL C API 自己的MySQL客户端:
		MySQL C API 命令行的上下左右,退格,删除按键乱码问题,先解决退格乱码
		MySQL C API 预处理二进制传输加快访问
		MySQL C API 多查询
		MySQL C API 时间和日期处理
		MySQL C API 的事务		

		


MySQL官方文档:

http://dev.mysql.com/doc/refman/5.5/en/



ubuntu搭建MySQL开发环境:

chunli@ubuntu14:~$ sudo apt-get install -y  mysql-server
chunli@ubuntu14:~$ sudo apt-get install -y  mysql-client
chunli@ubuntu14:~$ sudo apt-get install -y  libmysqld-dev



MySQL服务命令

chunli@ubuntu14:~$ sudo service mysql restart
mysql stop/waiting
mysql start/running, process 6944
chunli@ubuntu14:~$ echo $?
0
chunli@ubuntu14:~$



检查MySQL运行状态:

chunli@ubuntu14:~$ service mysql status
mysql start/running, process 7127


MySQL SQL


登陆测试:

chunli@ubuntu14:~$ mysql -uroot -p
Enter password: 11
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)


创建一个数据库

mysql> create database mydb1;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb1              |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

mysql>


显示数据库创建过程:

mysql> show create database mydb1;
+----------+------------------------------------------------------------------+
| Database | Create Database                                                  |
+----------+------------------------------------------------------------------+
| mydb1    | CREATE DATABASE `mydb1` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>



创建一个使用UTF8字符集的数据库

mysql> create database mydb2 character set utf8;
Query OK, 1 row affected (0.00 sec)

mysql> show create database mydb2;
+----------+----------------------------------------------------------------+
| Database | Create Database                                                |
+----------+----------------------------------------------------------------+
| mydb2    | CREATE DATABASE `mydb2` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+----------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>


创建一个使用UTF8字符集的数据库,带校对规则

mysql> create database mydb3 character set utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.00 sec)

mysql> show create database mydb3;
+----------+----------------------------------------------------------------+
| Database | Create Database                                                |
+----------+----------------------------------------------------------------+
| mydb3    | CREATE DATABASE `mydb3` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+----------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>



把数据库修改成UTF8字符集

mysql> alter database mydb1 character set utf8;
Query OK, 1 row affected (0.01 sec)

mysql> show create database mydb1;
+----------+----------------------------------------------------------------+
| Database | Create Database                                                |
+----------+----------------------------------------------------------------+
| mydb1    | CREATE DATABASE `mydb1` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+----------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>


选择数据库,创建表

mysql> use mydb2;
Database changed
mysql> create table t1(id int,name varchar(20));
Query OK, 0 rows affected (0.02 sec)

mysql>



查表结构:

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql>


mysql中的数据类型


bit 1位 但可以指定位数如bit<3>


int 2字节 可以指定最大位数如int<4> 最大为4位的整数


float 2个字节 可以指定最大的位数和最大的小数位数如float<5,2> 最大为一个5位的数小数位最多2位


double 4个字节 可以指定最大的位数和最大的小数位数如float<6,4> 最大为一个6位的数小数位最多4位


char 必须指定字符数,如char(5) 为不可变字符 即使存储的内容为‘ab‘,也是用5个字符的空间存储这个数据


varchar 必须指定字符数,如varchar(5) 为可变字符 如果存储的内容为‘ab‘,占用2个字符的空间如果为‘abc‘,则占用3个字符的空间


text: 大文本(大字符串)


blob二进制大数据 如图片音频文件视频文件


date: 日期 如‘1921-01-02‘


datetime: 日期时间 如‘1921-01-02 12:23:43‘


timeStamp: 时间戳自动赋值为当前日期时间



创建员工表:

mysql> use mydb2;
Database changed
mysql> create table employee(id int,name varchar(20),sex bit,birthday date,salary double, entry_date date,resume text);
Query OK, 0 rows affected (0.02 sec)

mysql> desc employee;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| id         | int(11)     | YES  |     | NULL    |       |
| name       | varchar(20) | YES  |     | NULL    |       |
| sex        | bit(1)      | YES  |     | NULL    |       |
| birthday   | date        | YES  |     | NULL    |       |
| salary     | double      | YES  |     | NULL    |       |
| entry_date | date        | YES  |     | NULL    |       |
| resume     | text        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

mysql> select * from employee;
Empty set (0.00 sec)

mysql> 

mysql> show create table employee\G
*************************** 1. row ***************************
       Table: employee
Create Table: CREATE TABLE `employee` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  `sex` bit(1) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `salary` double DEFAULT NULL,
  `entry_date` date DEFAULT NULL,
  `resume` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql>



修改表名:

mysql> rename table employee to worker;
Query OK, 0 rows affected (0.01 sec)

mysql> desc worker;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| id         | int(11)     | YES  |     | NULL    |       |
| name       | varchar(20) | YES  |     | NULL    |       |
| sex        | bit(1)      | YES  |     | NULL    |       |
| birthday   | date        | YES  |     | NULL    |       |
| salary     | double      | YES  |     | NULL    |       |
| entry_date | date        | YES  |     | NULL    |       |
| resume     | text        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

mysql>


删除表:

mysql> drop table worker;
Query OK, 0 rows affected (0.01 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql>


插入中文:

mysql> create table employee(id int,name varchar(20),sex bit,birthday date,salary double, entry_date date,resume text);
mysql> insert into employee(id,name,sex,birthday,salary,entry_date,resume) values(1,‘武松‘,1,‘1770-08-30‘,1500,‘1988-02-03‘,‘三碗不过岗‘);
mysql> insert into employee(id,name,sex,birthday,salary,entry_date,resume) values(1,‘吴用‘,1,‘1770-05-30‘,1500,‘1987-02-03‘,‘智取生辰纲‘);
mysql> insert into employee(id,name,sex,birthday,salary,entry_date,resume) values(1,‘林冲‘,1,‘1779-05-30‘,1500,‘1989-02-03‘,‘误入白虎节堂‘);
mysql> select * from employee;
+------+--------+------+------------+--------+------------+--------------------+
| id   | name   | sex  | birthday   | salary | entry_date | resume             |
+------+--------+------+------------+--------+------------+--------------------+
|    1 | 武松   |     | 1770-08-30 |   1500 | 1988-02-03 | 三碗不过岗         |
|    1 | 吴用   |     | 1770-05-30 |   1500 | 1987-02-03 | 智取生辰纲         |
|    1 | 林冲   |     | 1779-05-30 |   1500 | 1989-02-03 | 误入白虎节堂       |
+------+--------+------+------------+--------+------------+--------------------+
3 rows in set (0.00 sec)

mysql>



数据环境搭建:

create table student(
id int,
name varchar(20),
chinese int,
english int,
math int
);
insert into student(id,name,chinese,english,math) values(1,‘何东‘,80,85,90);
insert into student(id,name,chinese,english,math) values(2,‘权筝‘,90,95,95);
insert into student(id,name,chinese,english,math) values(3,‘何南‘,80,96,96);
insert into student(id,name,chinese,english,math) values(4,‘叶坦‘,81,97,85);
insert into student(id,name,chinese,english,math) values(5,‘何西‘,85,84,90);
insert into student(id,name,chinese,english,math) values(6,‘丁香‘,92,85,87);
insert into student(id,name,chinese,english,math) values(7,‘何北‘,75,81,80);
insert into student(id,name,chinese,english,math) values(8,‘唐娇‘,77,80,79);
insert into student(id,name,chinese,english,math) values(9,‘任知了‘,95,85,85);
insert into student(id,name,chinese,english,math) values(10,‘王越‘,94,85,84);
mysql> select * from student;
+------+-----------+---------+---------+------+
| id   | name      | chinese | english | math |
+------+-----------+---------+---------+------+
|    1 | 何东      |      80 |      85 |   90 |
|    2 | 权筝      |      90 |      95 |   95 |
|    3 | 何南      |      80 |      96 |   96 |
|    4 | 叶坦      |      81 |      97 |   85 |
|    5 | 何西      |      85 |      84 |   90 |
|    6 | 丁香      |      92 |      85 |   87 |
|    7 | 何北      |      75 |      81 |   80 |
|    8 | 唐娇      |      77 |      80 |   79 |
|    9 | 任知了    |      95 |      85 |   85 |
|   10 | 王越      |      94 |      85 |   84 |
+------+-----------+---------+---------+------+
10 rows in set (0.01 sec)

mysql>



求学生总分:

mysql> select * ,chinese+english+math 总分 from student order by 总分 desc;
+------+-----------+---------+---------+------+--------+
| id   | name      | chinese | english | math | 总分   |
+------+-----------+---------+---------+------+--------+
|    2 | 权筝      |      90 |      95 |   95 |    280 |
|    3 | 何南      |      80 |      96 |   96 |    272 |
|    9 | 任知了    |      95 |      85 |   85 |    265 |
|    6 | 丁香      |      92 |      85 |   87 |    264 |
|   10 | 王越      |      94 |      85 |   84 |    263 |
|    4 | 叶坦      |      81 |      97 |   85 |    263 |
|    5 | 何西      |      85 |      84 |   90 |    259 |
|    1 | 何东      |      80 |      85 |   90 |    255 |
|    7 | 何北      |      75 |      81 |   80 |    236 |
|    8 | 唐娇      |      77 |      80 |   79 |    236 |
+------+-----------+---------+---------+------+--------+
10 rows in set (0.00 sec)


增加一个字段:

mysql> select * from student;
+------+-----------+---------+---------+------+---------+
| id   | name      | chinese | english | math | classid |
+------+-----------+---------+---------+------+---------+
|    1 | 何东      |      80 |      85 |   90 |    NULL |
|    2 | 权筝      |      90 |      95 |   95 |    NULL |
|    3 | 何南      |      80 |      96 |   96 |    NULL |
|    4 | 叶坦      |      81 |      97 |   85 |    NULL |
|    5 | 何西      |      85 |      84 |   90 |    NULL |
|    6 | 丁香      |      92 |      85 |   87 |    NULL |
|    7 | 何北      |      75 |      81 |   80 |    NULL |
|    8 | 唐娇      |      77 |      80 |   79 |    NULL |
|    9 | 任知了    |      95 |      85 |   85 |    NULL |
|   10 | 王越      |      94 |      85 |   84 |    NULL |
+------+-----------+---------+---------+------+---------+
10 rows in set (0.00 sec)

mysql>



update表 where and

mysql> update student set classid=1 where id>=1 and id<=5;
Query OK, 5 rows affected (0.01 sec)
Rows matched: 5  Changed: 5  Warnings: 0

mysql> select * from student;
+------+-----------+---------+---------+------+---------+
| id   | name      | chinese | english | math | classid |
+------+-----------+---------+---------+------+---------+
|    1 | 何东      |      80 |      85 |   90 |       1 |
|    2 | 权筝      |      90 |      95 |   95 |       1 |
|    3 | 何南      |      80 |      96 |   96 |       1 |
|    4 | 叶坦      |      81 |      97 |   85 |       1 |
|    5 | 何西      |      85 |      84 |   90 |       1 |
|    6 | 丁香      |      92 |      85 |   87 |    NULL |
|    7 | 何北      |      75 |      81 |   80 |    NULL |
|    8 | 唐娇      |      77 |      80 |   79 |    NULL |
|    9 | 任知了    |      95 |      85 |   85 |    NULL |
|   10 | 王越      |      94 |      85 |   84 |    NULL |
+------+-----------+---------+---------+------+---------+
10 rows in set (0.00 sec)

mysql>



update表 where between and

mysql> update student set classid=2 where id between 4 and 10;
Query OK, 7 rows affected (0.01 sec)
Rows matched: 7  Changed: 7  Warnings: 0

mysql> select * from student;
+------+-----------+---------+---------+------+---------+
| id   | name      | chinese | english | math | classid |
+------+-----------+---------+---------+------+---------+
|    1 | 何东      |      80 |      85 |   90 |       1 |
|    2 | 权筝      |      90 |      95 |   95 |       1 |
|    3 | 何南      |      80 |      96 |   96 |       1 |
|    4 | 叶坦      |      81 |      97 |   85 |       2 |
|    5 | 何西      |      85 |      84 |   90 |       2 |
|    6 | 丁香      |      92 |      85 |   87 |       2 |
|    7 | 何北      |      75 |      81 |   80 |       2 |
|    8 | 唐娇      |      77 |      80 |   79 |       2 |
|    9 | 任知了    |      95 |      85 |   85 |       2 |
|   10 | 王越      |      94 |      85 |   84 |       2 |
+------+-----------+---------+---------+------+---------+
10 rows in set (0.00 sec)

mysql>


求各个班级的平均分:

mysql> select classid 班级编号,avg(chinese+english+math) 班级平均分 from student group by classid;
+--------------+-----------------+
| 班级编号     | 班级平均分      |
+--------------+-----------------+
|            1 |        269.0000 |
|            2 |        255.1429 |
+--------------+-----------------+
2 rows in set (0.00 sec)



Oracle分组机制很好,MySQL不伦不类的显示:

oracle中select中的字段必须要在group by 中

mysql> select name, classid 班级编号,avg(chinese+english+math) 班级平均分 from student group by classid;
+--------+--------------+-----------------+
| name   | 班级编号     | 班级平均分      |
+--------+--------------+-----------------+
| 何东   |            1 |        269.0000 |
| 叶坦   |            2 |        255.1429 |
+--------+--------------+-----------------+
2 rows in set (0.00 sec)



日期时间函数

获取当前日期和时间

mysql> select now() from dual;
+---------------------+
| now()               |
+---------------------+
| 2016-08-30 13:11:27 |
+---------------------+
1 row in set (0.00 sec)


获取当前日期和时间,简写方式

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2016-08-30 13:12:47 |
+---------------------+
1 row in set (0.00 sec)



获取当前日期

mysql> select current_date();
+----------------+
| current_date() |
+----------------+
| 2016-08-30     |
+----------------+
1 row in set (0.00 sec)


获取当前时间

mysql> select current_time();
+----------------+
| current_time() |
+----------------+
| 13:13:44       |
+----------------+
1 row in set (0.00 sec)


获取当前时间戳

mysql> select current_timestamp();
+---------------------+
| current_timestamp() |
+---------------------+
| 2016-08-30 13:14:19 |
+---------------------+
1 row in set (0.00 sec)


获取指定时间的日期:

mysql> select date(now());
+-------------+
| date(now()) |
+-------------+
| 2016-08-30  |
+-------------+
1 row in set (0.00 sec)


日期加减:

mysql> select date_add(now(),INTERVAL -1 day) 昨天 ,now()今天, date_add(now(),INTERVAL +1 day)明天 ;
+---------------------+---------------------+---------------------+
| 昨天                | 今天                | 明天                |
+---------------------+---------------------+---------------------+
| 2016-08-29 13:27:46 | 2016-08-30 13:27:46 | 2016-08-31 13:27:46 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

mysql>



年加减:

mysql> select date_add(now(),INTERVAL -1 year) 去年 ,now()今天, date_add(now(),INTERVAL +1 year)明年 ;
+---------------------+---------------------+---------------------+
| 去年                | 今天                | 明年                |
+---------------------+---------------------+---------------------+
| 2015-08-30 13:28:52 | 2016-08-30 13:28:52 | 2017-08-30 13:28:52 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

mysql>


创建班级表:

mysql> use mydb2;
Database changed
mysql> create table myclass(id INT(11) primary key auto_increment,name varchar(20) unique);
Query OK, 0 rows affected (0.02 sec)

mysql> desc myclass;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  | UNI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql>



插入数据:

mysql> insert into myclass(name)  values("宋江");
Query OK, 1 row affected (0.00 sec)

mysql> insert into myclass(name)  values("林冲");
Query OK, 1 row affected (0.01 sec)

mysql> insert into myclass(name)  values("李逵");
Query OK, 1 row affected (0.00 sec)

mysql> insert into myclass(name)  values("燕青");
Query OK, 1 row affected (0.01 sec)

mysql> insert into myclass(name)  values("武松");
Query OK, 1 row affected (0.02 sec)

mysql> select * from myclass;
+----+--------+
| id | name   |
+----+--------+
|  1 | 宋江   |
|  3 | 李逵   |
|  2 | 林冲   |
|  5 | 武松   |
|  4 | 燕青   |
+----+--------+
5 rows in set (0.01 sec)

mysql>


多表查询,环境搭建,模拟Oracle scott用户的表


-- 用root用户登录系统执行脚本

-- 创建数据库
create database mydb61 character set utf8 ; 

-- 选择数据库
use mydb61;

-- 增加 dbuser1 用户
-- 	创建用户‘dbuser61’密码为 ‘dbuser61’拥有操作数据库mydb61的所有权限
	GRANT ALL ON mydb61.* TO dbuser61 IDENTIFIED BY "dbuser61";
	flush privileges;

-- grant select,insert,update,delete on mydb61.* to dbuser61@localhost identified by "dbuser61";
-- grant select,insert,update,delete on mydb61.* to dbuser61@‘%‘ identified by "dbuser61";

-- 创建表

-- 创建部门表 并赋值
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept`(
	`deptno`     int(2) PRIMARY KEY,
 	`dname`       varchar(14) NOT NULL,
 	`loc`        	varchar(13)
)DEFAULT CHARSET=utf8;

INSERT INTO dept VALUES(10, ‘ACCOUNTING‘, ‘NEW YORK‘);
INSERT INTO dept VALUES(20, ‘RESEARCH‘, ‘DALLAS‘);
INSERT INTO dept VALUES(30, ‘SALES‘, ‘CHICAGO‘);
INSERT INTO dept VALUES(40, ‘OPERATIONS‘, ‘BOSTON‘);

commit;

-- 注意mysql的sql语言 约束如果起名字需要单独写在表后面
-- 创建员工表 并赋值
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp`(
	-- `empno`           int(4) constraint emp_empno_pk PRIMARY KEY,
	`empno`           int(4) PRIMARY KEY,
	`ename`          	varchar(10) NOT NULL,
	`job`            	varchar(9),
	`mgr`            	int(4),
	`hiredate`       	DATE,
	`sal`            	int ,
	`comm`           	int,
	`deptno`        	int(2) ,
	constraint emp_deptno_fk  foreign key(deptno) references dept(deptno)
)DEFAULT CHARSET=utf8;

--创建索引 
-- CREATE  INDEX MYSCOTT.IX_CAtbAuditOperInfo_OT ON MYSCOTT.EMP(ENAME) TABLESPACE ts_myscott2;
create index emp_ename_index on emp(ename);

--注意 日期格式不一样
INSERT INTO emp VALUES(7369, ‘SMITH‘, ‘CLERK‘, 7902, ‘1980-12-17‘, 800, NULL, 20);
INSERT INTO emp VALUES(7499, ‘ALLEN‘, ‘SALESMAN‘, 7698, ‘1981-02-20‘, 1600, 300, 30);
-- INSERT INTO emp(empno, ename, job, mgr, hiredate, sal,  deptno) VALUES(7499, ‘ALLEN‘, ‘SALESMAN‘, 7698, ‘1981-02-20‘, 1600, 30);
INSERT INTO emp VALUES(7521, ‘WARD‘, ‘SALESMAN‘, 7698, ‘1981-02-22‘, 1250, 500, 30);            
INSERT INTO emp VALUES(7566, ‘JONES‘, ‘MANAGER‘, 7839, ‘1981-04-02‘, 2975, NULL, 20);
INSERT INTO emp VALUES(7654, ‘MARTIN‘, ‘SALESMAN‘, 7698, ‘1981-09-28‘, 1250, 1400, 30);
INSERT INTO emp VALUES(7698, ‘BLAKE‘, ‘MANAGER‘, 7839, ‘1981-05-01‘, 2850, NULL, 30);
            
INSERT INTO emp VALUES(7782, ‘CLARK‘, ‘MANAGER‘, 7839, ‘1981-06-09‘, 2450, NULL, 10);
INSERT INTO emp VALUES(7788, ‘SCOTT‘, ‘ANALYST‘, 7566, ‘1987-04-19‘, 3000, NULL, 20);
INSERT INTO emp VALUES(7839, ‘KING‘, ‘PRESIDENT‘, NULL, ‘1981-11-17‘, 5000, NULL, 10);
            
INSERT INTO emp VALUES(7844, ‘TURNER‘, ‘SALESMAN‘, 7698, ‘1981-09-08‘, 1500, 0, 30);
INSERT INTO emp VALUES(7876, ‘ADAMS‘, ‘CLERK‘, 7788, ‘1987-05-23‘, 1100, NULL, 20);
INSERT INTO emp VALUES(7900, ‘JAMES‘, ‘CLERK‘, 7698, ‘1981-12-03‘, 950, NULL, 30);
            
INSERT INTO emp VALUES(7902, ‘FORD‘, ‘ANALYST‘, 7566, ‘1981-12-03‘, 3000, NULL, 20);
INSERT INTO emp VALUES(7934, ‘MILLER‘, ‘CLERK‘, 7782, ‘1982-01-23‘, 1300, NULL, 10);
commit;

-- 创建工资级别表 并赋值
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade`(
 	`grade`        	int,
 	`losal`           int,
 	`hisal`           int
)DEFAULT CHARSET=utf8;

INSERT INTO salgrade VALUES(1, 700, 1200);
INSERT INTO salgrade VALUES(2, 1201, 1400);
INSERT INTO salgrade VALUES(3, 1401, 2000);
INSERT INTO salgrade VALUES(4, 2001, 3000);
INSERT INTO salgrade VALUES(5, 3001, 9999);
commit;

--创建奖金表
DROP TABLE IF EXISTS `bonus`;
CREATE TABLE bonus(
	`ename`      VARCHAR(10),
 	`job`       VARCHAR(9),
 	`sal`      	int,
 	`comm`      int
)DEFAULT CHARSET=utf8;

commit;


验证环境搭建结果:

验证:mysql> show tables;
+------------------+
| Tables_in_mydb61 |
+------------------+
| bonus            |
| dept             |
| emp              |
| salgrade         |
+------------------+
4 rows in set (0.00 sec)

mysql> select * from bonus;
Empty set (0.00 sec)

mysql> select * from dept;
+--------+------------+----------+
| deptno | dname      | loc      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)

mysql> select * from emp;
+-------+--------+-----------+------+------------+------+------+--------+
| empno | ename  | job       | mgr  | hiredate   | sal  | comm | deptno |
+-------+--------+-----------+------+------------+------+------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800 | NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600 |  300 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250 |  500 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975 | NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250 | 1400 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850 | NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450 | NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000 | NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000 | NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500 |    0 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100 | NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950 | NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000 | NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300 | NULL |     10 |
+-------+--------+-----------+------+------------+------+------+--------+
14 rows in set (0.00 sec)

mysql> select * from salgrade;
+-------+-------+-------+
| grade | losal | hisal |
+-------+-------+-------+
|     1 |   700 |  1200 |
|     2 |  1201 |  1400 |
|     3 |  1401 |  2000 |
|     4 |  2001 |  3000 |
|     5 |  3001 |  9999 |
+-------+-------+-------+
5 rows in set (0.00 sec)

mysql>


多表查询,等值连接,显示员工编号,姓名,薪水,职位

结果与Oracle 一样

mysql> select e.empno,e.ename,e.sal,d.dname from emp e ,dept d where e.deptno = d.deptno;
+-------+--------+------+------------+
| empno | ename  | sal  | dname      |
+-------+--------+------+------------+
|  7782 | CLARK  | 2450 | ACCOUNTING |
|  7839 | KING   | 5000 | ACCOUNTING |
|  7934 | MILLER | 1300 | ACCOUNTING |
|  7369 | SMITH  |  800 | RESEARCH   |
|  7566 | JONES  | 2975 | RESEARCH   |
|  7788 | SCOTT  | 3000 | RESEARCH   |
|  7876 | ADAMS  | 1100 | RESEARCH   |
|  7902 | FORD   | 3000 | RESEARCH   |
|  7499 | ALLEN  | 1600 | SALES      |
|  7521 | WARD   | 1250 | SALES      |
|  7654 | MARTIN | 1250 | SALES      |
|  7698 | BLAKE  | 2850 | SALES      |
|  7844 | TURNER | 1500 | SALES      |
|  7900 | JAMES  |  950 | SALES      |
+-------+--------+------+------------+
14 rows in set (0.00 sec)



多表查询,where 不等值连接,显示员工编号,姓名,薪水,职位,薪水级别

mysql> select e.empno,e.ename,e.sal,s.grade from emp e ,salgrade s where e.sal<=s.hisal and e.sal>=s.losal;
+-------+--------+------+-------+
| empno | ename  | sal  | grade |
+-------+--------+------+-------+
|  7369 | SMITH  |  800 |     1 |
|  7499 | ALLEN  | 1600 |     3 |
|  7521 | WARD   | 1250 |     2 |
|  7566 | JONES  | 2975 |     4 |
|  7654 | MARTIN | 1250 |     2 |
|  7698 | BLAKE  | 2850 |     4 |
|  7782 | CLARK  | 2450 |     4 |
|  7788 | SCOTT  | 3000 |     4 |
|  7839 | KING   | 5000 |     5 |
|  7844 | TURNER | 1500 |     3 |
|  7876 | ADAMS  | 1100 |     1 |
|  7900 | JAMES  |  950 |     1 |
|  7902 | FORD   | 3000 |     4 |
|  7934 | MILLER | 1300 |     2 |
+-------+--------+------+-------+
14 rows in set (0.00 sec)



多表查询,between and 不等值连接,显示员工编号,姓名,薪水,职位,薪水级别

mysql> select e.empno,e.ename,e.sal,s.grade from emp e ,salgrade s where e.sal between s.losal and s.hisal;
+-------+--------+------+-------+
| empno | ename  | sal  | grade |
+-------+--------+------+-------+
|  7369 | SMITH  |  800 |     1 |
|  7499 | ALLEN  | 1600 |     3 |
|  7521 | WARD   | 1250 |     2 |
|  7566 | JONES  | 2975 |     4 |
|  7654 | MARTIN | 1250 |     2 |
|  7698 | BLAKE  | 2850 |     4 |
|  7782 | CLARK  | 2450 |     4 |
|  7788 | SCOTT  | 3000 |     4 |
|  7839 | KING   | 5000 |     5 |
|  7844 | TURNER | 1500 |     3 |
|  7876 | ADAMS  | 1100 |     1 |
|  7900 | JAMES  |  950 |     1 |
|  7902 | FORD   | 3000 |     4 |
|  7934 | MILLER | 1300 |     2 |
+-------+--------+------+-------+
14 rows in set (0.00 sec)



多表查询,分组, 按部门统计员工人数:显示部门号,部门名称,部门人数

mysql> select d.dname,d.deptno,count(e.empno) from dept d,emp e where e.deptno=d.deptno group by d.deptno ,d.dname;
+------------+--------+----------------+
| dname      | deptno | count(e.empno) |
+------------+--------+----------------+
| ACCOUNTING |     10 |              3 |
| RESEARCH   |     20 |              5 |
| SALES      |     30 |              6 |
+------------+--------+----------------+
3 rows in set (0.01 sec)


多表查询,分组, 外连接,按部门统计员工人数,并显示40号部门信息

MySQL不支持Oracle的外连接语法:
mysql> select d.dname,d.deptno,count(e.empno) from dept d,emp e where e.deptno=d.deptno(+) group by d.deptno ,d.dname;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘) group by d.deptno ,d.dname‘ at line 1

MySQL 独有左外连接,右外连接

mysql> select d.dname,d.deptno,count(e.empno) from dept d left join emp e on e.deptno=d.deptno group by d.deptno ,d.dname; 
+------------+--------+----------------+
| dname      | deptno | count(e.empno) |
+------------+--------+----------------+
| ACCOUNTING |     10 |              3 |
| RESEARCH   |     20 |              5 |
| SALES      |     30 |              6 |
| OPERATIONS |     40 |              0 |
+------------+--------+----------------+
4 rows in set (0.00 sec)

mysql>


[面试难点]显示 不是管理者的信息:左外连接,滤空

mysql> select * from emp;
+-------+--------+-----------+------+------------+------+------+--------+
| empno | ename  | job       | mgr  | hiredate   | sal  | comm | deptno |
+-------+--------+-----------+------+------------+------+------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800 | NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600 |  300 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250 |  500 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975 | NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250 | 1400 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850 | NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450 | NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000 | NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000 | NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500 |    0 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100 | NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950 | NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000 | NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300 | NULL |     10 |
+-------+--------+-----------+------+------------+------+------+--------+
14 rows in set (0.00 sec)

mysql> 
mysql> select concat(e.ename,‘的老板是‘,ifnull(b.ename,‘他自己‘)) 员工与老板  from emp e left join emp b on e.mgr=b.empno;
+---------------------------+
| 员工与老板                |
+---------------------------+
| SMITH的老板是FORD         |
| ALLEN的老板是BLAKE        |
| WARD的老板是BLAKE         |
| JONES的老板是KING         |
| MARTIN的老板是BLAKE       |
| BLAKE的老板是KING         |
| CLARK的老板是KING         |
| SCOTT的老板是JONES        |
| KING的老板是他自己        |
| TURNER的老板是BLAKE       |
| ADAMS的老板是SCOTT        |
| JAMES的老板是BLAKE        |
| FORD的老板是JONES         |
| MILLER的老板是CLARK       |
+---------------------------+
14 rows in set (0.00 sec)


MySQL 乱码的原因:


mysql> show variables like ‘character%‘;
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql>


MySQL乱码话题:

更改客户端和网络发送的字符集为GBK,查看原UTF编码的中文就会乱码

chunli@ubuntu14:~$ mysql -uroot -p --default_character_set=gbk
mysql> show variables like ‘character%‘;
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | gbk                        |
| character_set_connection | gbk                        |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | gbk                        |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> select *from mydb2.employee;
+------+------+------+------------+--------+------------+--------------+
| id   | name | sex  | birthday   | salary | entry_date | resume       |
+------+------+------+------------+--------+------------+--------------+
|    1 |  |     | 1770-08-30 |   1500 | 1988-02-03 | 糧
|    1 | ★渀戀猀瀀;|     | 1770-05-30 |   1500 | 1987-02-03 | ℅★渀戀猀瀀; |
|    1 |      | 1779-05-30 |   1500 | 1989-02-03 | 欃°怆簀
+------+------+------+------------+--------+------------+--------------+
3 rows in set (0.00 sec)


插入一条记录试试:我的SHELL是UTF8编码的
mysql>  insert into employee(id,name,sex,birthday,salary,entry_date,resume) values(1,‘林冲‘,1,‘1779-05-30‘,1500,‘1989-02-03‘,‘误入白虎节堂‘);
Query OK, 1 row affected, 1 warning (0.02 sec)

mysql> select *from mydb2.employee;
+------+--------+------+------------+--------+------------+-------------------+
| id   | name   | sex  | birthday   | salary | entry_date | resume            |
+------+--------+------+------------+--------+------------+-------------------+
|    1 |    |     | 1770-08-30 |   1500 | 1988-02-03 |      |
|    1 | ★渀戀猀瀀;  |     | 1770-05-30 |   1500 | 1987-02-03 | ℅★渀戀猀瀀;      |
|    1 |  |     | 1779-05-30 |   1500 | 1989-02-03 | 欃°怆     |
|    1 | 林冲 |     | 1779-05-30 |   1500 | 1989-02-03 | 譿紀乶芆堂 |
+------+--------+------+------------+--------+------------+-------------------+
4 rows in set (0.00 sec)

mysql> 

我把shell的字符集改为GBK的试试:新插入一条记录:
mysql> insert into employee(id,name,sex,birthday,salary,entry_date,resume) values(1,‘林冲‘,1,‘1779-05-30‘,1500,‘1989-02-03‘,‘误入白虎节堂‘);
Query OK, 1 row affected (0.02 sec)

mysql> select *from mydb2.employee;
+------+--------+------+------------+--------+------------+-------------------+
| id   | name   | sex  | birthday   | salary | entry_date | resume            |
+------+--------+------+------------+--------+------------+-------------------+
|    1 | 武松   |     | 1770-08-30 |   1500 | 1988-02-03 | 三碗不过岗        |
|    1 | 吴用   |     | 1770-05-30 |   1500 | 1987-02-03 | 智取生辰纲        |
|    1 | 林冲   |     | 1779-05-30 |   1500 | 1989-02-03 | 误入白虎节堂      |
|    1 | 鏋楀啿 |     | 1779-05-30 |   1500 | 1989-02-03 | 璇?叆鐧借檸鑺傚爞 |
|    1 | 林冲   |     | 1779-05-30 |   1500 | 1989-02-03 | 误入白虎节堂      |
+------+--------+------+------------+--------+------------+-------------------+
5 rows in set (0.00 sec)

mysql>  show variables like ‘character%‘;
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | gbk                        |
| character_set_connection | gbk                        |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | gbk                        |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)



MySQL乱码分析:

第一层因素:

mysql的自身的设置
mysql有六处使用了字符集分别为client 、connection、database、results、server 、system。
mysql> show variables like ‘character%‘;
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

	
	
mysql -uroot -p --default_character_set=gbk; (影响数据的输入和输出)
	
mysql> show variables like ‘character%‘;
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | gbk                        |
| character_set_connection | gbk                        |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | gbk                        |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

insert into worker(id,name,sex,birthday,salary,entry_date,resume) values(3,‘赵六‘,0,‘1985-09-21‘,7000,‘2012-08-24‘,‘一个小小牛‘);
====>错误现象	
mysql> insert into worker(id,name,sex,birthday,salary,entry_date,resume) values(3,‘赵六‘,0,‘1985-09-21‘,7000,‘2012-08-24‘,‘一个小小牛‘);
ERROR 1366 (HY000): Incorrect string value: ‘\x80\xE4\xB8\xAA\xE5\xB0...‘ for column ‘resume‘ at row 1
mysql> 
====>结论: 让你的客户端 服务器 连接 ,都必须设置成一样 utf8 gbk


第二层因素

操作系统语言环境的设置
a)操作系统的总体的语言环境
[mysql01@localhost ~]$ cat /etc/sysconfig/i18n 
LANG="zh_CN.UTF-8"
[mysql01@localhost ~]$ 
b)当前用户的语言环境  linux的操作系统是基于多用户的操作系统
OLDPWD=/home/mysql01
[mysql01@localhost ~]$ env | grep LANG*
LANG=zh_CN.UTF-8
[mysql01@localhost ~]$ 

=====>当前用户的LANG设置能屏蔽操作系统语言环境设置					

实现:修改当前用户的语言环境 
[mysql01@localhost ~]$ env | grep LANG
LANG=C
[mysql01@localhost ~]$ 				

insert into worker(id,name,sex,birthday,salary,entry_date,resume) values(3,‘赵六六‘,0,‘1985-09-21‘,7000,‘2012-08-24‘,‘一个小牛‘);		
						


第三层因素

你的应用软件的本身 文件的 存储问题....

文件存储
最常用有2种方式: utf8  code936  
====  gbk转宽字节的函数....wide winskd函数  gbk转成宽字节(Unicode 2)
//备份mysql数据库
$ mysqldump -uroot -p mydb2 >  2.sql

//恢复msql数据库
$ mysqldump -uroot -p mydb2 < 2.sql



MySQL C API 编程


我的系统环境:

:
root@ubuntu14:~# uname --a
Linux ubuntu14 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux


mysql头文件:
root@ubuntu14:/usr/include/mysql# find / -name mysql.h
/usr/include/mysql/mysql.h

mysql动态库文件:
root@ubuntu14:~# find / -iname *mysqlclient.so
/usr/lib/x86_64-linux-gnu/libmysqlclient.so


MySQL C API Hello World程序

World程序
chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mysql/mysql.h>

int main(void)
{
	MYSQL mysql;
	MYSQL *connect = NULL;
	
	connect = mysql_init(&mysql);
	if(connect == NULL)
	{
		printf("mysql_init err \n");
		return -1;
	}
	mysql_close(&mysql);
	printf("Hello MySQL C API \n");
	return 0;
}
chunli@ubuntu14:~$ 

正常编译:
chunli@ubuntu14:~$ gcc main.c -Wall 
/tmp/cccvHvcb.o: In function `main‘:
main.c:(.text+0x30): undefined reference to `mysql_init‘
main.c:(.text+0x61): undefined reference to `mysql_close‘
collect2: error: ld returned 1 exit status
chunli@ubuntu14:~$ 

加mysqlclient动态库
chunli@ubuntu14:~$ gcc main.c -l mysqlclient 
chunli@ubuntu14:~$ ./a.out 
Hello MySQL C API 
chunli@ubuntu14:~$ 

chunli@ubuntu14:~$ ldd a.out 
	linux-vdso.so.1 =>  (0x00007ffdb5fc5000)
	libmysqlclient.so.18 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 (0x00007fcd8f5fe000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcd8f239000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fcd8f020000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fcd8ee1c000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fcd8ebfe000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fcd8e8f8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fcd8fb36000)
chunli@ubuntu14:~$


MySQL C API 的select 程序

chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mysql/mysql.h>

int main(void)
{
	MYSQL  mysql;
	MYSQL  *connect = NULL;
	int    ret = 0;
	//初始化	MYSQL *mysql_init(MYSQL *mysql) 
	connect = mysql_init(&mysql);
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		//返回错误码
		printf("%s\n",mysql_error(&mysql));	//返回错误信息
		return ret;
	}
	printf("mysql_init ok!\n");
	//登陆 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) 
	connect = mysql_real_connect(connect,"localhost","root","11","mydb61",0,NULL,0);
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	printf("mysql_real_connect ok!\n");
	//查询	int mysql_query(MYSQL *mysql, const char *stmt_str)
	const char *query = "select * from emp";
	ret = mysql_query(&mysql,query);
	if(ret != 0)
	{
		ret = mysql_errno(&mysql);	
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	//获取结果集 MYSQL_RES *mysql_store_result(MYSQL *mysql) 
	MYSQL_RES *result = mysql_store_result(&mysql);
	//遍历每一行 MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) 
	//从mysql.h中找到 typedef char **MYSQL_ROW; 可以看出,这是二级指针
	MYSQL_ROW row = NULL;
	while (row =  mysql_fetch_row(result))
	{
		printf("%s,%s,%s,%s,%s,%s,%s,%s\n",row[0],row[1],row[2],row[3],row[4],row[5],row[6],row[7]);
	}
	//释放结果集,结果集是二级指针
	mysql_free_result(result);
	
	//Closes a previously opened connection
	mysql_close(&mysql);
	return 0;
}
chunli@ubuntu14:~$ gcc main.c -l mysqlclient  && ./a.out 
mysql_init ok!
mysql_real_connect ok!
7369,SMITH,CLERK,7902,1980-12-17,800,(null),20
7499,ALLEN,SALESMAN,7698,1981-02-20,1600,300,30
7521,WARD,SALESMAN,7698,1981-02-22,1250,500,30
7566,JONES,MANAGER,7839,1981-04-02,2975,(null),20
7654,MARTIN,SALESMAN,7698,1981-09-28,1250,1400,30
7698,BLAKE,MANAGER,7839,1981-05-01,2850,(null),30
7782,CLARK,MANAGER,7839,1981-06-09,2450,(null),10
7788,SCOTT,ANALYST,7566,1987-04-19,3000,(null),20
7839,KING,PRESIDENT,(null),1981-11-17,5000,(null),10
7844,TURNER,SALESMAN,7698,1981-09-08,1500,0,30
7876,ADAMS,CLERK,7788,1987-05-23,1100,(null),20
7900,JAMES,CLERK,7698,1981-12-03,950,(null),30
7902,FORD,ANALYST,7566,1981-12-03,3000,(null),20
7934,MILLER,CLERK,7782,1982-01-23,1300,(null),10
chunli@ubuntu14:~$ 

验证:
chunli@ubuntu14:~$ mysql -uroot -p11 -Ne "use mydb61;select * from emp;"
+------+--------+-----------+------+------------+------+------+------+
| 7369 |  SMITH |     CLERK | 7902 | 1980-12-17 |  800 | NULL | 20   |
| 7499 |  ALLEN |  SALESMAN | 7698 | 1981-02-20 | 1600 | 300  | 30   |
| 7521 |   WARD |  SALESMAN | 7698 | 1981-02-22 | 1250 | 500  | 30   |
| 7566 |  JONES |   MANAGER | 7839 | 1981-04-02 | 2975 | NULL | 20   |
| 7654 | MARTIN |  SALESMAN | 7698 | 1981-09-28 | 1250 | 1400 | 30   |
| 7698 |  BLAKE |   MANAGER | 7839 | 1981-05-01 | 2850 | NULL | 30   |
| 7782 |  CLARK |   MANAGER | 7839 | 1981-06-09 | 2450 | NULL | 10   |
| 7788 |  SCOTT |   ANALYST | 7566 | 1987-04-19 | 3000 | NULL | 20   |
| 7839 |   KING | PRESIDENT | NULL | 1981-11-17 | 5000 | NULL | 10   |
| 7844 | TURNER |  SALESMAN | 7698 | 1981-09-08 | 1500 | 0    | 30   |
| 7876 |  ADAMS |     CLERK | 7788 | 1987-05-23 | 1100 | NULL | 20   |
| 7900 |  JAMES |     CLERK | 7698 | 1981-12-03 |  950 | NULL | 30   |
| 7902 |   FORD |   ANALYST | 7566 | 1981-12-03 | 3000 | NULL | 20   |
| 7934 | MILLER |     CLERK | 7782 | 1982-01-23 | 1300 | NULL | 10   |
+------+--------+-----------+------+------------+------+------+------+
chunli@ubuntu14:~$



MySQL C API 显示数据,自适应字段的个数:

chunli@ubuntu14:~$ gcc main.c -l mysqlclient  && ./a.out 
mysql_init ok!
mysql_real_connect ok!
10	ACCOUNTING	NEW YORK	
20	RESEARCH	DALLAS	
30	SALES	CHICAGO	
40	OPERATIONS	BOSTON	
chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mysql/mysql.h>

int main(void)
{
	MYSQL  mysql;
	MYSQL  *connect = NULL;
	int    ret = 0;
	//初始化	MYSQL *mysql_init(MYSQL *mysql) 
	connect = mysql_init(&mysql);
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		//返回错误码
		printf("%s\n",mysql_error(&mysql));	//返回错误信息
		return ret;
	}
	printf("mysql_init ok!\n");
	//登陆 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) 
	connect = mysql_real_connect(connect,"localhost","root","11","mydb61",0,NULL,0);
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	printf("mysql_real_connect ok!\n");
	//查询	int mysql_query(MYSQL *mysql, const char *stmt_str)
	const char *query = "select * from dept";
	ret = mysql_query(&mysql,query);
	if(ret != 0)
	{
		ret = mysql_errno(&mysql);	
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	//获取结果集 MYSQL_RES *mysql_store_result(MYSQL *mysql) 
	MYSQL_RES *result = mysql_store_result(&mysql);
	//获取每行有多少列
	unsigned int num  = mysql_field_count(&mysql);
	//遍历每一行 MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) 
	//从mysql.h中找到 typedef char **MYSQL_ROW; 可以看出,这是二级指针
	MYSQL_ROW row = NULL;
	while (row =  mysql_fetch_row(result))
	{
		unsigned int i = 0; 
		for(i=0;i<num;i++)
		{
			printf("%s\t",row[i]);
		}
		printf("\n");
	}
	//释放结果集,结果集是二级指针
	mysql_free_result(result);
	
	//Closes a previously opened connection
	mysql_close(&mysql);
	return 0;
}
chunli@ubuntu14:~$ gcc main.c -l mysqlclient  && ./a.out 
mysql_init ok!
mysql_real_connect ok!
10	ACCOUNTING	NEW YORK	
20	RESEARCH	DALLAS	
30	SALES	CHICAGO	
40	OPERATIONS	BOSTON	
chunli@ubuntu14:~$ 

验证:
chunli@ubuntu14:~$ mysql -uroot -p11 -Ne "use mydb61;select * from dept;"
+----+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 |   RESEARCH |   DALLAS |
| 30 |      SALES |  CHICAGO |
| 40 | OPERATIONS |   BOSTON |
+----+------------+----------+
chunli@ubuntu14:~$



MySQL C API  增加表头的输出:

chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mysql/mysql.h>

int main(void)
{
	MYSQL  mysql;
	MYSQL  *connect = NULL;
	int    ret = 0;
	unsigned int i = 0; 
	connect = mysql_init(&mysql);		//初始化MYSQL *mysql_init(MYSQL *mysql) 
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		//返回错误码
		printf("%s\n",mysql_error(&mysql));	//返回错误信息
		return ret;
	}
	connect = mysql_real_connect(connect,"localhost","root","11","mydb61",0,NULL,0);//登陆
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	const char *query = "select * from emp";
	ret = mysql_query(&mysql,query);	//查询	int mysql_query(MYSQL *mysql, const char *stmt_str)
	if(ret != 0)
	{
		ret = mysql_errno(&mysql);	
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	MYSQL_RES *result = mysql_store_result(&mysql);		//获取结果集 MYSQL_RES *mysql_store_result(MYSQL *mysql) 
	unsigned int num  = mysql_field_count(&mysql);		//获取每行有多少列
	MYSQL_FIELD *fields = mysql_fetch_fields(result);	//获取表头
	for(i=0;i<num;i++)	//打印表头
	{
		printf("%s\t",fields[i].name);
	}
	printf("\n");
	
	
	MYSQL_ROW row = NULL;
	while ((row = mysql_fetch_row(result)))			//打印数据
	{
		for(i=0;i<num;i++)
		{
			printf("%s\t",row[i]);
		}
		printf("\n");
	}
	mysql_free_result(result);		//释放结果集,结果集是二级指针
	mysql_close(&mysql);			//Closes a previously opened connection
	return 0;
}
chunli@ubuntu14:~$ gcc main.c -l mysqlclient -Wall   && ./a.out 
empno	ename	job	mgr	hiredate	sal	comm	deptno	
7369	SMITH	CLERK	7902	1980-12-17	800	(null)	20	
7499	ALLEN	SALESMAN	7698	1981-02-20	1600	300	30	
7521	WARD	SALESMAN	7698	1981-02-22	1250	500	30	
7566	JONES	MANAGER	7839	1981-04-02	2975	(null)	20	
7654	MARTIN	SALESMAN	7698	1981-09-28	1250	1400	30	
7698	BLAKE	MANAGER	7839	1981-05-01	2850	(null)	30	
7782	CLARK	MANAGER	7839	1981-06-09	2450	(null)	10	
7788	SCOTT	ANALYST	7566	1987-04-19	3000	(null)	20	
7839	KING	PRESIDENT	(null)	1981-11-17	5000	(null)	10	
7844	TURNER	SALESMAN	7698	1981-09-08	1500	0	30	
7876	ADAMS	CLERK	7788	1987-05-23	1100	(null)	20	
7900	JAMES	CLERK	7698	1981-12-03	950	(null)	30	
7902	FORD	ANALYST	7566	1981-12-03	3000	(null)	20	
7934	MILLER	CLERK	7782	1982-01-23	1300	(null)	10	
chunli@ubuntu14:~$ 

验证:
chunli@ubuntu14:~$ mysql -uroot -p11 -Ne "use mydb61;select * from emp;"
+------+--------+-----------+------+------------+------+------+------+
| 7369 |  SMITH |     CLERK | 7902 | 1980-12-17 |  800 | NULL | 20   |
| 7499 |  ALLEN |  SALESMAN | 7698 | 1981-02-20 | 1600 | 300  | 30   |
| 7521 |   WARD |  SALESMAN | 7698 | 1981-02-22 | 1250 | 500  | 30   |
| 7566 |  JONES |   MANAGER | 7839 | 1981-04-02 | 2975 | NULL | 20   |
| 7654 | MARTIN |  SALESMAN | 7698 | 1981-09-28 | 1250 | 1400 | 30   |
| 7698 |  BLAKE |   MANAGER | 7839 | 1981-05-01 | 2850 | NULL | 30   |
| 7782 |  CLARK |   MANAGER | 7839 | 1981-06-09 | 2450 | NULL | 10   |
| 7788 |  SCOTT |   ANALYST | 7566 | 1987-04-19 | 3000 | NULL | 20   |
| 7839 |   KING | PRESIDENT | NULL | 1981-11-17 | 5000 | NULL | 10   |
| 7844 | TURNER |  SALESMAN | 7698 | 1981-09-08 | 1500 | 0    | 30   |
| 7876 |  ADAMS |     CLERK | 7788 | 1987-05-23 | 1100 | NULL | 20   |
| 7900 |  JAMES |     CLERK | 7698 | 1981-12-03 |  950 | NULL | 30   |
| 7902 |   FORD |   ANALYST | 7566 | 1981-12-03 | 3000 | NULL | 20   |
| 7934 | MILLER |     CLERK | 7782 | 1982-01-23 | 1300 | NULL | 10   |
+------+--------+-----------+------+------------+------+------+------+
chunli@ubuntu14:~$


MySQL C API  中文问题,设置语言集

刚才的那个程序,不能显示中文:


但是中文乱码:
chunli@ubuntu14:~$ gcc main.c -l mysqlclient -Wall   && ./a.out 
id	name	sex	birthday	salary	entry_date	resume	
1	??		1770-08-30	1500	1988-02-03	?????	
1	??		1770-05-30	1500	1987-02-03	?????	
1	??		1779-05-30	1500	1989-02-03	??????	
1	???		1779-05-30	1500	1989-02-03	?????????	
1	??		1779-05-30	1500	1989-02-03	??????	
chunli@ubuntu14:~$ 
应该是这样的:第4行是做实验时故意乱码的
chunli@ubuntu14:~$ mysql -uroot -p11 -Ne "use mydb2;select * from employee;"
+------+-----------+------+------------+------+------------+---------------------------+
|    1 |      武松 |     | 1770-08-30 | 1500 | 1988-02-03 | 三碗不过岗                |
|    1 |      吴用 |     | 1770-05-30 | 1500 | 1987-02-03 | 智取生辰纲                |
|    1 |      林冲 |     | 1779-05-30 | 1500 | 1989-02-03 | 误入白虎节堂              |
|    1 |    鏋楀啿 |     | 1779-05-30 | 1500 | 1989-02-03 | 璇?叆鐧借檸鑺傚爞         |
|    1 |      林冲 |     | 1779-05-30 | 1500 | 1989-02-03 | 误入白虎节堂              |
+------+-----------+------+------------+------+------------+---------------------------+

解决办法:mysql_query(&mysql,"set names utf8");	//设置语言集
chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mysql/mysql.h>

int main(void)
{
	MYSQL  mysql;
	MYSQL  *connect = NULL;
	int    ret = 0;
	unsigned int i = 0; 
	connect = mysql_init(&mysql);		//初始化MYSQL *mysql_init(MYSQL *mysql) 
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		//返回错误码
		printf("%s\n",mysql_error(&mysql));	//返回错误信息
		return ret;
	}
	//connect = mysql_real_connect(connect,"localhost","root","11","mydb61",0,NULL,0);//登陆
	connect = mysql_real_connect(connect,"localhost","root","11","mydb2",0,NULL,0);//登陆
	if(connect == NULL)
	{
		ret = mysql_errno(&mysql);		
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	const char *query = "select * from employee";
	ret = mysql_query(&mysql,"set names utf8");	//设置语言集
	ret = mysql_query(&mysql,query);	//查询	int mysql_query(MYSQL *mysql, const char *stmt_str)
	if(ret != 0)
	{
		ret = mysql_errno(&mysql);	
		printf("%s\n",mysql_error(&mysql));
		return ret;
	}
	MYSQL_RES *result = mysql_store_result(&mysql);		//获取结果集 MYSQL_RES *mysql_store_result(MYSQL *mysql) 
	unsigned int num  = mysql_field_count(&mysql);		//获取每行有多少列
	MYSQL_FIELD *fields = mysql_fetch_fields(result);	//获取表头
	for(i=0;i<num;i++)	//打印表头
	{
		printf("%s\t",fields[i].name);
	}
	printf("\n");
	
	
	MYSQL_ROW row = NULL;
	while ((row = mysql_fetch_row(result)))			//打印数据
	{
		for(i=0;i<num;i++)
		{
			printf("%s\t",row[i]);
		}
		printf("\n");
	}
	mysql_free_result(result);		//释放结果集,结果集是二级指针
	mysql_close(&mysql);			//Closes a previously opened connection
	return 0;
}
chunli@ubuntu14:~$ gcc main.c -l mysqlclient -Wall   && ./a.out 
id	name	sex	birthday	salary	entry_date	resume	
1	武松		1770-08-30	1500	1988-02-03	三碗不过岗	
1	吴用		1770-05-30	1500	1987-02-03	智取生辰纲	
1	林冲		1779-05-30	1500	1989-02-03	误入白虎节堂	
1	鏋楀啿		1779-05-30	1500	1989-02-03	璇?叆鐧借檸鑺傚爞	
1	林冲		1779-05-30	1500	1989-02-03	误入白虎节堂	
chunli@ubuntu14:~$



游标,一行一行的返回,不在把结果集全部存储在本地
[待完善...]



MySQL C API 自己的MySQL客户端:

chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>

int main(void)
{
	int 	ret = 0, i = 0;
	MYSQL 	mysql;
	MYSQL	*connect = NULL;
	char	sqlbuf[2048];
	connect = mysql_init(&mysql) ;
	if (connect == NULL)
	{
		ret =  mysql_errno(&mysql) ;
		printf("func mysql_init() err \n");
		return ret;
	}
	connect = mysql_real_connect(connect, "localhost", "root", "11", "mydb2", 0, NULL, 0);
	if (connect == NULL)
	{
		ret =  mysql_errno(&mysql) ;
		printf("func mysql_init() err \n");
		return ret;	
	}
	while (1)
	{
		memset(sqlbuf, 0, sizeof(sqlbuf));
		printf("MySQL> ");
		fgets(sqlbuf,sizeof(sqlbuf),stdin);
		if ( 0 == strncmp(sqlbuf , "exit" , 4) || 0 == strncmp(sqlbuf , "EXIT" , 4))
		{
			printf("Bye\n");
			break;
		}
		ret = mysql_query(&mysql, "set names utf8");
		if (ret != 0)
		{
			ret =  mysql_errno(&mysql) ;
			printf("func mysql_query() err \n");
			return ret;	
		}
		ret = mysql_query(&mysql, sqlbuf);
		if (ret != 0)
		{
			ret =  mysql_errno(&mysql) ;
			printf("func mysql_query() err \n");
			return ret;	
		}
		if (strncmp("select", sqlbuf, 6)==0 ||  strncmp("SELECT", sqlbuf, 6)==0)
		{
			MYSQL_RES *result = mysql_store_result(&mysql);
			unsigned int  num = mysql_field_count(&mysql) ;
			MYSQL_FIELD  *fields = mysql_fetch_fields(result);
			for (i = 0; i<num; i++)
			{
				printf("%s\t",  fields[i].name);
			}
			printf("\n");
			MYSQL_ROW row = NULL;
			while ((row = mysql_fetch_row(result) ) )
			{
				for (i=0; i<num; i++)
				{
					printf("%s\t", row[i]);
				}
				printf("\n");
			}
			mysql_free_result(result);		
		}
	}
	mysql_close(&mysql);
	return ret;
}
// create table t33(id int, name varchar(20))
chunli@ubuntu14:~$ 




编译运行:
chunli@ubuntu14:~$ gcc main.c -l mysqlclient -Wall   && ./a.out 
MySQL> select * from employee
id	name	sex	birthday	salary	entry_date	resume	
1	武松		1770-08-30	1500	1988-02-03	三碗不过岗	
1	吴用		1770-05-30	1500	1987-02-03	智取生辰纲	
1	林冲		1779-05-30	1500	1989-02-03	误入白虎节堂	
1	鏋楀啿		1779-05-30	1500	1989-02-03	璇?叆鐧借檸鑺傚爞	
1	林冲		1779-05-30	1500	1989-02-03	误入白虎节堂	
MySQL> create table t33(id int, name varchar(20))
MySQL> exit
Bye
chunli@ubuntu14:~$ 


验证:
chunli@ubuntu14:~$ mysql -uroot -p11 -Ne "use mydb2;select * from employee;"
+------+-----------+------+------------+------+------------+---------------------------+
|    1 |      武松 |     | 1770-08-30 | 1500 | 1988-02-03 | 三碗不过岗                |
|    1 |      吴用 |     | 1770-05-30 | 1500 | 1987-02-03 | 智取生辰纲                |
|    1 |      林冲 |     | 1779-05-30 | 1500 | 1989-02-03 | 误入白虎节堂              |
|    1 |    鏋楀啿 |     | 1779-05-30 | 1500 | 1989-02-03 | 璇?叆鐧借檸鑺傚爞         |
|    1 |      林冲 |     | 1779-05-30 | 1500 | 1989-02-03 | 误入白虎节堂              |
+------+-----------+------+------------+------+------------+---------------------------+
chunli@ubuntu14:~$ mysql -uroot -p11 -Ne "use mydb2;show tables;"
+----------+
| employee |
|  myclass |
|  student |
|       t1 |
|      t33 |
+----------+
chunli@ubuntu14:~$



命令行的上下左右,退格,删除按键乱码问题,先解决退格乱码

chunli@ubuntu14:~$ cat main.c 


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <mysql/mysql.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#include <mysql/mysql.h>

#include <termios.h>

struct termios oldterm;
void setstty2()//设置输入退格键不回显
{
	//system("stty erase ^H");//执行shell命令也可以 用来设置读取用户键盘输入的时候退格键不回显

	struct termios term;
	if(tcgetattr(STDIN_FILENO, &term) == -1)//得到系统termion的设置
	{
		printf("tcgetattr error is %s\n", strerror(errno));
		return;
	}

	oldterm = term;//保留当前termios设置以便程序退出的时候可以恢复termios //tty

	/*
	term.c_lflag &= ~ICANON;//取消ICANON选项不规范输入
	term.c_lflag |= ICANON;//设置ICANON选项(规范输入)
	term.c_cc字段为要设置的具体特殊输入字符如c_cc[VERASE]代表退格键,
	term.c_cc[VERASE] = ‘\b‘;意思为把退格键修改为‘\b‘
	VERASE代表向前擦出一个字符,VINTR代表发送ctrl + C中断信号ctrl + c的ASCII码为3
	例如term.c_cc[VINTR] = ‘\t‘;意思为将tab键设置为终端信号
	tcsetattr中第二个参数说明TCSAFLUSH发送了所有输出后更改才生效在更改发生时未读取的所有输入数据都被删除
	TCSANOW:更改立即生效
	TCSADRAIN:发送了所有输出后更改才发生如果更改输出参数则应该使用该选项
	 */
	term.c_cc[VERASE] = ‘\b‘;//‘\b‘为退格键的ASCII码
	if (tcsetattr(STDIN_FILENO, TCSANOW, &term) == -1)//设置系统termion
	{
		printf("tcsetattr error is %s\n", strerror(errno));
	}
	return;
}

void setstty()//设置输入退格键不回显
{
	system("stty erase ^H");//执行shell命令也可以 用来设置读取用户键盘输入的时候退格键不回显

}

void returnstty()//恢复系统的termios设置
{
	if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &oldterm) == -1)//设置系统termion
	{
		printf("tcsetattr error is %s\n", strerror(errno));
	}
	return;
}


int main(int arg, char *args[])
{
	int 			ret = 0, i=0;
	MYSQL 			mysql;
	MYSQL			*connect;
	MYSQL_RES 		*result;
	MYSQL_ROW		row;
	MYSQL_FIELD 	*fields;
	unsigned int 	num_fields;

	if (arg < 4)
	{
		printf("please enter: %s localhost user password dbname\n", args[0]);
		return -1;
	}

	setstty();//设置输入退格键不回显

	mysql_init(&mysql);

	//连接到mysql server
	connect = mysql_real_connect(&mysql, args[1], args[2], args[3], args[4],0, 0, 0);
	if (connect == NULL)
	{
		printf("connect error, %s\n", mysql_error(&mysql));
		return -1;
	}

	ret = mysql_query(connect, "SET NAMES utf8");		//设置字符集为UTF8
	if (ret != 0)
	{
		printf("设置字符集错误, %s\n", mysql_error(&mysql));
		return ret;
	}

	char buf[4096];
	for( ; ; )
	{
		memset(buf, 0, sizeof(buf));
		//strcpy(buf, "mysql>");
		//write(STDOUT_FILENO, buf, strlen(buf));
		//memset(buf, 0, sizeof(buf));
		//read(STDIN_FILENO, buf, sizeof(buf));

		printf("mysql> ");
		fgets(buf,sizeof(buf),stdin);

		/* EXIT(exit):退出 */
		if ( 0 == strncmp(buf , "exit" , 4) || 0 == strncmp(buf , "EXIT" , 4) ||
				0 == strncmp(buf , "quit" , 4) || 0 == strncmp(buf , "QUIT" , 4) ) 
		{
			break;
		}	 

		//printf("buf:%s \n", buf);
		ret = mysql_query(connect, buf); 
		if (ret != 0 )
		{
			printf("func mysql_query() err: %s", mysql_error(&mysql) );
			continue;
		}
		else
		{
			//printf("ok\n");
		}

		if ( (strncmp(buf, "select", 6) == 0) || (strncmp(buf, "SELECT", 6) == 0) ||
				(strncmp(buf, "show", 4) == 0) || (strncmp(buf, "SHOW", 4) == 0) ||
				(strncmp(buf, "desc", 4) == 0) || (strncmp(buf, "DESC", 4) == 0) )
		{
			//获取查询结果
			result = mysql_store_result(&mysql); 

			//获取列表头信息信息
			fields = mysql_fetch_fields(result);
			num_fields = mysql_num_fields(result);

			for (i=0; i<num_fields; i++)
			{
				printf("%s\t", fields[i].name);
			}
			printf("\n");

			//按照行获取数据 检索结果集的下一行。
			while((row = mysql_fetch_row(result)))
			{
				for (i=0; i<mysql_num_fields(result); i++)
				{
					printf("%s\t ",row[i]);
				}
				printf("\n");
			}

			mysql_free_result(result);//free result after you get the result
		}
		else
		{
			//printf("")mysql_affected_rows(connect); 
		}
	}	

	mysql_close(connect);		//断开与SQL server的连接
	//returnstty();//恢复系统的termios设置

	return 0;
}


chunli@ubuntu14:~$ 

编译运行:
chunli@ubuntu14:~$ gcc main.c -l mysqlclient -Wall   && ./a.out 127.0.0.1 root 11 mydb2
mysql> show tables
Tables_in_mydb2	
employee	 
myclass	 
student	 
t1	 
t33	 
mysql> select^[[A^[[B^[[D^[[C^[[ 退格键可以使用


预处理二进制传输加快访问

chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>


#define STRING_SIZE 50
 
#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
#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(?,?,?)"

//int main(char **argv, int argc)
int main(char *argv[], int argc)
{
	int 	ret = 0, i = 0;
	
	MYSQL 	*mysql;
	MYSQL	*connect = NULL;
	char	sqlbuf[2048];
	
	mysql = mysql_init(NULL) ;	
	if (mysql == NULL)
	{
		ret =  mysql_errno(&mysql) ;
		printf("func mysql_init() err \n");
		return ret;
	}
	printf("func mysql_init() ok \n");
	
	connect = mysql_real_connect(mysql, "localhost", "root", "11", "mydb2", 0, NULL, 0);
	if (connect == NULL)
	{
		ret =  mysql_errno(&mysql) ;
		printf("func mysql_init() err \n");
		return ret;	
	}
	printf("func mysql_real_connect() ok \n");
	 
	MYSQL_STMT    *stmt;
	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);  //初始化预处理环境句柄  MYSQL_STMT *stmt
	if (!stmt)
	{
	  fprintf(stderr, " mysql_stmt_init(), out of memory\n");
	  exit(0);
	}
	if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE)))  //向预处理环境句柄stmt 中添加sql( 带有占位符)
	{
	  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);   //获取sql语言中 占位符 的个数
	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;  //设置第一个占位符的属性
	bind[0].buffer= (char *)&int_data;
	bind[0].is_null= 0;
	bind[0].length= 0;
	 
	/* STRING PARAM */
	bind[1].buffer_type= MYSQL_TYPE_STRING; //设置第2个占位符的属性
	bind[1].buffer= (char *)str_data;
	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; //设置第3个占位符的属性
	bind[2].buffer= (char *)&small_data;
	bind[2].is_null= &is_null;
	bind[2].length= 0;
	 
	/* Bind the buffers */
	if (mysql_stmt_bind_param(stmt, bind))  //把设置好的属性 加入预处理环境stmt中
	{
	  fprintf(stderr, " mysql_stmt_bind_param() failed\n");
	  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
	  exit(0);
	}
	 
	/* Specify the data values for the first row */    //准备插入数据
	int_data=http://www.mamicode.com/ 10;             /* integer */"MySQL", STRING_SIZE); /* string  */
	str_length= strlen(str_data);
	 
	/* INSERT SMALLINT data as NULL */
	is_null= 1;
	 
	/* 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);
	}
	 
	/* Specify data values for second row, then re-execute the statement */
	int_data=http://www.mamicode.com/ 1000;"The most popular Open Source database", STRING_SIZE);
	str_length= strlen(str_data);
	small_data=http://www.mamicode.com/ 1000;         /* smallint */" 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);
	}
	
	
	 mysql_close(connect);	

	
	printf("hello...\n");
	return ret;
}

 
// create table t33(id int, name varchar(20))








chunli@ubuntu14:~$ gcc main.c -l mysqlclient  && ./a.out 
main.c: In function ‘main’:
main.c:28:3: warning: passing argument 1 of ‘mysql_errno’ from incompatible pointer type [enabled by default]
   ret =  mysql_errno(&mysql) ;
   ^
In file included from main.c:4:0:
/usr/include/mysql/mysql.h:371:22: note: expected ‘struct MYSQL *’ but argument is of type ‘struct MYSQL **’
 unsigned int STDCALL mysql_errno(MYSQL *mysql);
                      ^
main.c:37:3: warning: passing argument 1 of ‘mysql_errno’ from incompatible pointer type [enabled by default]
   ret =  mysql_errno(&mysql) ;
   ^
In file included from main.c:4:0:
/usr/include/mysql/mysql.h:371:22: note: expected ‘struct MYSQL *’ but argument is of type ‘struct MYSQL **’
 unsigned int STDCALL mysql_errno(MYSQL *mysql);
                      ^
func mysql_init() ok 
func mysql_real_connect() ok 
 prepare, INSERT successful
 total parameters in INSERT: 3
 total affected rows(insert 1): 1
 total affected rows(insert 2): 1
hello...
chunli@ubuntu14:~$



MySQL C API 多查询


chunli@ubuntu14:~$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>


int	process_result_set(MYSQL *mysql, MYSQL_RES *result)
{
	int		ret = 0, i = 0;
	unsigned int  num = 0;
	
	if (mysql==NULL || result==NULL)
	{
		ret = 0;
		printf("func process_result_set() err:%d, check  if (mysql==NULL || result==NULL) \n", ret);
		return ret;
	}
	num = mysql_field_count(mysql) ;
	
	//求表头
	MYSQL_FIELD  *fields = mysql_fetch_fields(result);
	for (i = 0; i<num; i++)
	{
		printf("%s\t",  fields[i].name);
	}
	printf("\n");
	
	//按照行 求内容
	MYSQL_ROW row = NULL;
	while ( row = mysql_fetch_row(result) ) 
	{
		for (i=0; i<num; i++)
		{
			printf("%s\t", row[i]);
		}
		printf("\n");
	}
	
	return  0;
}


int main()
{
	int 	ret = 0;
	int		status = 0;
	
	MYSQL 	*mysql;
	MYSQL	*connect = NULL;
	MYSQL_RES *result ;
	
	
	mysql = mysql_init(NULL) ;	
	if (mysql == NULL)
	{
		ret =  mysql_errno(mysql) ;
		printf("func mysql_init() err \n");
		return ret;
	}
	printf("func mysql_init() ok \n");
	
	connect = mysql_real_connect(mysql, "localhost", "root", "11", "mydb2", 0, NULL, CLIENT_MULTI_STATEMENTS);
	if (connect == NULL)
	{
		ret =  mysql_errno(mysql) ;
		printf("func mysql_init() err \n");
		return ret;	
	}

	/* execute multiple statements */
	status = mysql_query(mysql,
						"DROP TABLE IF EXISTS test_table;						CREATE TABLE test_table(id INT);						INSERT INTO test_table VALUES(10);						UPDATE test_table SET id=20 WHERE id=10;						SELECT * FROM test_table;						DROP TABLE test_table");
	if (status)
	{
		printf("Could not execute statement(s)");
		mysql_close(mysql);
		exit(0);
	}
	/* process each statement result */
	do {
			/* did current statement return data? */
			result = mysql_store_result(mysql);
			if (result)  //select语句
			{
				/* yes; process rows and free the result set */
				//打桩
				process_result_set(mysql, result);
				mysql_free_result(result);
			}
			else /* no result set or error */
			{
				if (mysql_field_count(mysql) == 0)
				{
					printf("%lld rows affected\n",
					mysql_affected_rows(mysql));
				}
				else /* some error occurred */
				{
					printf("Could not retrieve result set\n");
					break;
				}
			}
			/* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
			if ((status = mysql_next_result(mysql)) > 0)
				printf("Could not execute statement\n");
	} while (status == 0);
	
	
	 mysql_close(connect);	

	
	printf("hello...\n");
	return ret;
}

 
// create table t33(id int, name varchar(20))







chunli@ubuntu14:~$ gcc main.c -l mysqlclient  && ./a.out 
func mysql_init() ok 
0 rows affected
0 rows affected
1 rows affected
1 rows affected
id	
20	
0 rows affected
hello...
chunli@ubuntu14:~$


时间和日期MySQL C API处理

先在MySQL创建表:
mysql> create table test_table (date_field date,  time_field time,  timestamp_field timestamp );
Query OK, 0 rows affected (0.02 sec)

源程序:


chunli@ubuntu14:~$ cat main.c 


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <mysql/mysql.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#include <mysql/mysql.h>


int main()
{
	int 		ret = 0, status = 0;
	MYSQL 		*mysql;
	MYSQL_RES 	*result;
	
	mysql =mysql_init(NULL);
	mysql =mysql_real_connect(mysql, "localhost", "root", "11", "mydb2", 0, NULL, CLIENT_MULTI_STATEMENTS );
	if (mysql == NULL)
	{
		ret = mysql_errno(mysql);
		printf("%s", mysql_error(mysql));
		printf("func mysql_real_connect() err :%d\n", ret);
		return ret;
	}
	else
	{
		printf(" ok......\n");
	}
	
	MYSQL_TIME  ts;
	MYSQL_BIND  bind[3];
	MYSQL_STMT  *stmt;
	
	 //注意
	 // 创建的表语句
	 // create table test_table (date_field date,  time_field time,  timestamp_field timestamp );
	char query[1024] = "INSERT INTO test_table(date_field, time_field, timestamp_field) VALUES(?,?,?)";
	
	stmt = mysql_stmt_init(mysql);
	if (!stmt)
	{
		fprintf(stderr, " mysql_stmt_init(), out of memory\n");
		exit(0);
	}
	if (mysql_stmt_prepare(stmt, query, strlen(query))) //向环境句柄中添加sql语言  带有占位符
	{
		fprintf(stderr, "mysql_stmt_prepare(), INSERT failed\n");
		fprintf(stderr, "%s\n", mysql_stmt_error(stmt));
		exit(0);
	}
	/* set up input buffers for all 3 parameters */
	bind[0].buffer_type= MYSQL_TYPE_DATE;  //设置绑定变量属性
	bind[0].buffer= (char *)&ts;
	bind[0].is_null= 0;
	bind[0].length= 0;
	//
	bind[1]= bind[2]= bind[0];
	//...
	
	mysql_stmt_bind_param(stmt, bind);
	
	/* supply the data to be sent in the ts structure */
	ts.year= 2002;
	ts.month= 02;
	ts.day= 03;
	
	ts.hour= 10;
	ts.minute= 45;
	ts.second= 20;
	
	mysql_stmt_execute(stmt);
	
	// 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);
	}
  
	mysql_close(mysql);
}

编译运行:
chunli@ubuntu14:~$ gcc main.c -l mysqlclient  && ./a.out 
 ok......
chunli@ubuntu14:~$ 


验证:
mysql> select * from test_table;
+------------+------------+---------------------+
| date_field | time_field | timestamp_field     |
+------------+------------+---------------------+
| 2002-02-03 | 00:00:00   | 2002-02-03 00:00:00 |
+------------+------------+---------------------+
1 row in set (0.00 sec)

mysql>



MySQL C  API 的事务

环境准备
mysql> use mydb2;
mysql> drop table test_table;
mysql> commit;
mysql> create table test_table(col1 int, col2 varchar(10), col3 varchar(10));



主程序
chunli@ubuntu14:~$ cat main.c 


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <mysql/mysql.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#include <mysql/mysql.h>


//oracle的事务:事务起始标志 DML语言 (oracle默认事务似是打开的)
//MYSQL默认是自动提交的 (每执行一个sql语言都给你自动提交) 
/*
MySQL set autocommit = 0或1分别什么啊,哪个是自动提交啊
要熟练使用mysql的帮助文档在里面查找autocommit就会有相应的注释比我在这里直接给你说要深刻得多。

autocoomit是事务根据mysql的文档如果等于1是立即提交。但在transction中只有遇到commit或rollback才提交。希望对你有用。

*/

/*
MYSQL默认是自动提交的也就是你提交一个QUERY它就直接执行我们可以通过
     set autocommit=0  禁止自动提交
     set autocommit=1 开启自动提交 
mysql中INNODB引擎才支持事务处理默认是自动提交的
另外一种常用的MYISAM引擎是不支持事务的本身就没有事务的概念 
*/

#define BEGIN_TRAN 		"START TRANSACTION"
#define SET_TRAN			"SET AUTOCOMMIT=0"  
#define UNSET_TRAN		"SET AUTOCOMMIT=1"
#define COMMIT_TRAN		"COMMIT"
#define ROLLBACK_TRAN	"ROLLBACK"

int mysql_BeginTran(MYSQL *mysql)
{
	int ret = 0;

	//--执行事务开始SQL
	ret = mysql_query(mysql, BEGIN_TRAN);
	if (ret != 0)
	{
		printf("func mysql_query() err: %d\n", ret);
		return ret;
	}

	//--设置事务手动提交
	ret = mysql_query(mysql, SET_TRAN);
	if (ret != 0)
	{
		printf("func mysql_query() err: %d\n", ret);
		return ret;
	}

	return ret;
}
	
	
int mysql_Rollback(MYSQL *mysql)
{
	int ret = 0;
	
	//--事务回滚操作
	ret = mysql_query(mysql, ROLLBACK_TRAN);
	if (ret != 0)
	{
		printf("func mysql_query() err: %d\n", ret);
		return ret;
	}
	
	//--恢复事务自动提交标志
	ret = mysql_query(mysql, UNSET_TRAN);
	if (ret != 0)
	{
		printf("func mysql_query() err: %d\n", ret);
		return ret;
	}
	
	return ret;
}

int mysql_Commit(MYSQL *mysql)
{
	int ret = 0;
	
	//--执行事务提交SQL
	ret = mysql_query(mysql, COMMIT_TRAN);
	if (ret != 0)
	{
		printf("func mysql_query() err: %d\n", ret);
		return ret;
	}
	
	//--恢复自动提交设置
	ret = mysql_query(mysql, UNSET_TRAN);
	if (ret != 0)
	{
		printf("func mysql_query() err: %d\n", ret);
		return ret;
	}
	
	return ret;
}


// drop table test_table
// 建表 create table test_table(col1 int, col2 varchar(10), col3 varchar(10)); 

#define sql01 "INSERT INTO test_table(col1,col2,col3) VALUES(10, ‘10‘, ‘1‘)"
#define sql02 "INSERT INTO test_table(col1,col2,col3) VALUES(20, ‘20‘, ‘2‘)"
#define sql03 "INSERT INTO test_table(col1,col2,col3) VALUES(30, ‘30‘, ‘3‘)"
#define sql04 "INSERT INTO test_table(col1,col2,col3) VALUES(40, ‘40‘, ‘4‘)"

int main()
{
	int 		ret = NULL;
	
	MYSQL 		*mysql;
	
	MYSQL_RES 	*res;
	MYSQL_ROW	row;
	char 		*query;

	
	mysql = mysql_init(NULL);
	
	mysql =mysql_real_connect(mysql, "localhost", "root", "11", "mydb2", 0, NULL, 0 );
	if (mysql == NULL)
	{
		ret = mysql_errno(mysql);
		printf("func mysql_real_connect() err\n");
		return ret;
	}
	else
	{
		printf(" ok......\n");
	}
	
	ret = mysql_BeginTran(mysql); //修改事务的属性,变成不自动 提交 
	if (ret != 0)
	{
		printf("mysql_BeginTran() err:%d\n", ret);
		return ret;
	}
	ret = mysql_query(mysql, sql01);
	if (ret != 0)
	{
		printf("mysql_query() err:%d\n", ret);
		return ret;
	}
	ret = mysql_query(mysql, sql02);
	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;
	}
	
	
	ret = mysql_BeginTran(mysql);
	if (ret != 0)
	{
		printf("mysql_BeginTran() err:%d\n", ret);
		return ret;
	}
	ret = mysql_query(mysql, sql03);
	if (ret != 0)
	{
		printf("mysql_query() err:%d\n", ret);
		return ret;
	}
	ret = mysql_query(mysql, sql04);
	if (ret != 0)
	{
		printf("mysql_query() err:%d\n", ret);
		return ret;
	}
	ret = mysql_Rollback(mysql);
	if (ret != 0)
	{
		printf("mysql_Rollback() err:%d\n", ret);
		return ret;
	}
		
	mysql_close(mysql);
		
}





chunli@ubuntu14:~$ 

编译运行:

chunli@ubuntu14:~$ gcc main.c -l mysqlclient  && ./a.out 
 ok......
chunli@ubuntu14:~$ 


验证:
mysql> select * from test_table;
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
|   10 | 10   | 1    |
|   20 | 20   | 2    |
+------+------+------+
2 rows in set (0.00 sec)

mysql>



本文出自 “魂斗罗” 博客,谢绝转载!

数据库编程5 MySQL C API 开发