linux - mysql编程使用

本文最后更新于:2021年4月23日 下午

概览:linux - mysql编程使用.

安装mysql

命令:

1
sudo apt install mysql-server -y

安装 libmysqlclient-dev

安装完这个之后,才会有对应的头文件!!

但是不幸的是,安装中碰到了依赖问题

折叠/查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
colourso@colourso-virtual-machine:/usr/include$ sudo apt-get install libmysqlclient-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:

下列软件包有未满足的依赖关系:
libmysqlclient-dev : 依赖: libssl-dev (>= 1.1.1-1ubuntu2.1~18.04.5~) 但是它将不会被安装
依赖: zlib1g-dev 但是它将不会被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
于是一个一个解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
colourso@colourso-virtual-machine:/usr/include$ sudo apt install libssl-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:

下列软件包有未满足的依赖关系:
libssl-dev : 依赖: libssl1.1 (= 1.1.1-1ubuntu2.1~18.04.9) 但是 1.1.1c-1ubuntu4 正要被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
colourso@colourso-virtual-machine:/usr/include$ sudo apt install libssl1.1
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
libssl1.1 已经是最新版 (1.1.1c-1ubuntu4)
libssl1.1 已设置为手动安装。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 47 个软件包未被升级。
colourso@colourso-virtual-machine:/usr/include$ sudo apt install libssl-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:

下列软件包有未满足的依赖关系:
libssl-dev : 依赖: libssl1.1 (= 1.1.1-1ubuntu2.1~18.04.9) 但是 1.1.1c-1ubuntu4 正要被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
colourso@colourso-virtual-machine:/usr/include$ sudo apt install libssl1.1=1.1.1-1ubuntu2.1~18.04.9
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
下列软件包将被【降级】:
libssl1.1
升级了 0 个软件包,新安装了 0 个软件包,降级了 1 个软件包,要卸载 0 个软件包,有 47 个软件包未被升级。
需要下载 1,301 kB 的归档。
解压缩后将会空出 81.9 kB 的空间。
您希望继续执行吗? [Y/n] y
获取:1 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-updates/main amd64 libssl1.1 amd64 1.1.1-1ubuntu2.1~18.04.9 [1,301 kB]
已下载 1,301 kB,耗时 5秒 (241 kB/s)
正在预设定软件包 ...
dpkg: 警告: 即将把 libssl1.1:amd64 从 1.1.1c-1ubuntu4 降级到 1.1.1-1ubuntu2.1~18
.04.9
(正在读取数据库 ... 系统当前共安装有 153861 个文件和目录。)
准备解压 .../libssl1.1_1.1.1-1ubuntu2.1~18.04.9_amd64.deb ...
正在解压 libssl1.1:amd64 (1.1.1-1ubuntu2.1~18.04.9) 并覆盖 (1.1.1c-1ubuntu4) ...
正在设置 libssl1.1:amd64 (1.1.1-1ubuntu2.1~18.04.9) ...
正在处理用于 libc-bin (2.30-0ubuntu2) 的触发器 ...

然后重新安装libmysqlclient-dev
1
2
3
4
5
6
7
8
9
10
11
12
13
colourso@colourso-virtual-machine:/usr/include$ sudo apt-get install libmysqlclient-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:

下列软件包有未满足的依赖关系:
libmysqlclient-dev : 依赖: zlib1g-dev 但是它将不会被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

只剩下了一个问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
olourso@colourso-virtual-machine:/usr/include$ sudo apt-get install zlib1g-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:

下列软件包有未满足的依赖关系:
zlib1g-dev : 依赖: zlib1g (= 1:1.2.11.dfsg-0ubuntu2) 但是 1:1.2.11.dfsg-1ubuntu3 正要被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
colourso@colourso-virtual-machine:/usr/include$ sudo apt-get install zlib1g-dev=1:1.2.11.dfsg-0ubuntu2
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是
因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件
包尚未被创建或是它们已被从新到(Incoming)目录移出。
下列信息可能会对解决问题有所帮助:

下列软件包有未满足的依赖关系:
zlib1g-dev : 依赖: zlib1g (= 1:1.2.11.dfsg-0ubuntu2) 但是 1:1.2.11.dfsg-1ubuntu3 正要被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

colourso@colourso-virtual-machine:/usr/include$ sudo apt-get install zlib1g=1:1.2.11.dfsg-0ubuntu2
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
下列软件包将被【降级】:
zlib1g
升级了 0 个软件包,新安装了 0 个软件包,降级了 1 个软件包,要卸载 0 个软件包,有 47 个软件包未被升级。
需要下载 56.5 kB 的归档。
解压缩后会消耗 7,168 B 的额外空间。
您希望继续执行吗? [Y/n] y
获取:1 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic/main amd64 zlib1g amd64 1:1.2.11.dfsg-0ubuntu2 [56.5 kB]
已下载 56.5 kB,耗时 0秒 (233 kB/s)
dpkg: 警告: 即将把 zlib1g:amd64 从 1:1.2.11.dfsg-1ubuntu3 降级到 1:1.2.11.dfsg-0ubuntu2
(正在读取数据库 ... 系统当前共安装有 153862 个文件和目录。)
准备解压 .../zlib1g_1%3a1.2.11.dfsg-0ubuntu2_amd64.deb ...
正在解压 zlib1g:amd64 (1:1.2.11.dfsg-0ubuntu2) 并覆盖 (1:1.2.11.dfsg-1ubuntu3) ...
正在设置 zlib1g:amd64 (1:1.2.11.dfsg-0ubuntu2) ...
正在处理用于 libc-bin (2.30-0ubuntu2) 的触发器 ...

解决之后再次重新安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
colourso@colourso-virtual-machine:/usr/include$ sudo apt-get install libmysqlclient-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
将会同时安装下列软件:
libmysqlclient20 libssl-dev zlib1g-dev
建议安装:
libssl-doc
下列【新】软件包将被安装:
libmysqlclient-dev libmysqlclient20 libssl-dev zlib1g-dev
升级了 0 个软件包,新安装了 4 个软件包,要卸载 0 个软件包,有 47 个软件包未被升级。
需要下载 3,418 kB 的归档。
解压缩后会消耗 18.3 MB 的额外空间。
您希望继续执行吗? [Y/n] y
获取:1 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-updates/main amd64 libmysqlclient20 amd64 5.7.33-0ubuntu0.18.04.1 [687 kB]
获取:2 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-updates/main amd64 libssl-dev amd64 1.1.1-1ubuntu2.1~18.04.9 [1,566 kB]
获取:3 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic/main amd64 zlib1g-dev amd64 1:1.2.11.dfsg-0ubuntu2 [176 kB]
获取:4 https://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-updates/main amd64 libmysqlclient-dev amd64 5.7.33-0ubuntu0.18.04.1 [989 kB]
已下载 3,418 kB,耗时 3秒 (1,142 kB/s)
正在选中未选择的软件包 libmysqlclient20:amd64
(正在读取数据库 ... 系统当前共安装有 153862 个文件和目录。)
准备解压 .../libmysqlclient20_5.7.33-0ubuntu0.18.04.1_amd64.deb ...
正在解压 libmysqlclient20:amd64 (5.7.33-0ubuntu0.18.04.1) ...
正在选中未选择的软件包 libssl-dev:amd64
准备解压 .../libssl-dev_1.1.1-1ubuntu2.1~18.04.9_amd64.deb ...
正在解压 libssl-dev:amd64 (1.1.1-1ubuntu2.1~18.04.9) ...
正在选中未选择的软件包 zlib1g-dev:amd64
准备解压 .../zlib1g-dev_1%3a1.2.11.dfsg-0ubuntu2_amd64.deb ...
正在解压 zlib1g-dev:amd64 (1:1.2.11.dfsg-0ubuntu2) ...
正在选中未选择的软件包 libmysqlclient-dev。
准备解压 .../libmysqlclient-dev_5.7.33-0ubuntu0.18.04.1_amd64.deb ...
正在解压 libmysqlclient-dev (5.7.33-0ubuntu0.18.04.1) ...
正在设置 libmysqlclient20:amd64 (5.7.33-0ubuntu0.18.04.1) ...
正在设置 libssl-dev:amd64 (1.1.1-1ubuntu2.1~18.04.9) ...
正在设置 zlib1g-dev:amd64 (1:1.2.11.dfsg-0ubuntu2) ...
正在设置 libmysqlclient-dev (5.7.33-0ubuntu0.18.04.1) ...
正在处理用于 man-db (2.8.7-3) 的触发器 ...
正在处理用于 libc-bin (2.30-0ubuntu2) 的触发器 ...
colourso@colourso-virtual-machine:/usr/include$

查看用户名、密码

一般这些内容都存放在了mysql这个数据库中的user这张表中。

要注意的是,在mysql5.7版本下,用户的密码字段是authentication_string。而以前的版本是password

使用命令查看:

1
2
3
4
5
6
7
8
9
10
11
mysql> use mysql;

mysql> select user,host,authentication_string from user;
+------------------+-----------+-------------------------------------------+
| user | host | authentication_string |
+------------------+-----------+-------------------------------------------+
| root | localhost | |
| mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| debian-sys-maint | localhost | *2CEF8CEE0693E61E8C4D5B1CB1907484489D5082 |
+------------------+-----------+-------------------------------------------+

修改密码

1
update mysql set authentication_string='asdf' where user='root';

登录

1
2
3
mysql -uroot -p
mysql -u用户名 -p
之后输入密码
  • 比较好奇的是阿里云的这台服务器,普通用户不能登录,必须使用root用户!

mysql注意事项

  • 数据库的名字区分大小写,表名也区分大小写

  • 同时创建的数据库默认字符集是拉丁语,所以创建数据库时可以在指定字符集

1
2
3
4
5
6
7
8
9
10
11
12
mysql> show create database mytest;
+----------+-------------------------------------------------------------------+
| Database | Create Database |
+----------+-------------------------------------------------------------------+
| mytest | CREATE DATABASE `mytest` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-------------------------------------------------------------------+

mysql> create database mytest2 character set utf8;
--指定字符集为utf8

mysql> alter database mytest character set utf8;
--修改数据库字符集

查看表的结构

1
desc tablename;

程序

头文件

1
#include <mysql/mysql.h>

编译:记得带上mysqlclient

1
2
3
4
5
6
g++ test.cpp -o test -lmysqlclient

编译错误常见问题:
__gxx_personality_V0 --> -lstdc++
dlclose/dlopen/dlsym --> -ldl
my_getsystime/clock_gettime --> lrt

基础函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//初始化
MYSQL* mysql_init(MYSQL* mysql);

//错误查看和处理
unsigned int mysql_errno(MYSQL *mysql);
char* mysql_error(MYSQL *mysql);

//建立连接
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);
//port = 0表示使用默认端口

//执行SQL语句,万能函数能够执行任何再mysql上执行成功的任意语句
int mysql_query(MYSQL* mysql,const char* stmt_str);

//获取结果
MYSQL_RES * mysql_store_result(MYSQL * mysql);
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

//释放内存
void mysql_free_result(MYSQL_RES *result);

//关闭连接
void mysql_close(MYSQL* mysql);

基础连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <list>
#include <mysql/mysql.h>
#include <error.h>
#include <string.h>
#include <iostream>
#include <string>

using namespace std;

int main(){

MYSQL *con = mysql_init(NULL);//初始化

if(con == NULL){
cout<<"error1"<<endl;
exit(0);
}

con = mysql_real_connect(con,"localhost","root","asdf","mytest",0,NULL,0);

if(con == NULL){
printf("mysql connect error : [%s]\n",mysql_error(mysql));
exit(0);
}

mysql_query(con, "SELECT sname,type FROM stu");

//从表中检索完整的结果集
MYSQL_RES *result = mysql_store_result(con);

//返回结果集中的列数
int num_fields = mysql_num_fields(result);

//返回所有字段结构的数组
MYSQL_FIELD *fields = mysql_fetch_fields(result);

//从结果集中获取下一行,将对应的用户名和密码,存入map中
while (MYSQL_ROW row = mysql_fetch_row(result))
{
string temp1(row[0]);
string temp2(row[1]);
cout<<temp1<<" -- "<<temp2<<endl;
}

return 0;
}

查询

1
2
3
4
int mysql_query(MYSQL* mysql,const char * query);
//1. 不要给语句加上分号,或者\g
//2. 不能用于包含二进制数据的查询,会把\0当作结束标志,这时使用 mysql_real_query
//3. 查询成功返回0,出现错误,返回非0

例如

1
2
3
4
5
char * query = "insert into mytable values(3,'li')";
int ret = mysql_query(conn,query);
if(ret != 0){
printf("query error: %s\n",mysql_error(conn));
}

获取结果集

  1. 调用mysql_store_result() 将整个结果集全部取出来。
  2. 调用mysql_use_result()初始化获取操作,但暂时不取回任何记录。

视结果集的条目数选择获取结果集的函数。

两种方法均通过mysql_fetch_row()来访问每一条数据。

1
2
3
MYSQL_RES * mysql_store_result(MYSQL * mysql);

//返回 MYSQL_RES *结果集指针,失败返回NULL

解析结果集

通过游标一行一行fetch结果集中的数据,根据游标使用的一般特性,应使用循环结构,到达结尾或者出错,返回NULL。

1
2
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
//返回下一行的MYSQL_ROW结构,没有了或者错误了返回NULL

例如

1
2
3
4
5
6
MYSQL_RES *result =  mysql_store_result(MYSQL * mysql);

MYSQL_ROW row;
while(row = mysql_fetch_row(result)){
printf("%s %s \d",row[0],row[1]);
}

获取列数

1
2
3
unsigned int mysql_field_count(MYSQL* mysql);

unsigned int mysql_num_fields(MYSQL_RES* result);

获取表头

1
2
3
4
5
MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES* result);
//获取全部

MYSQL_FIELD* mysql_fetch_field(MYSQL_RES* result);
//获取单个

实例

1
2
3
4
5
6
int num = mysql_field_count(conn);
MYSQL_FIELD* fields = mysql_fetch_fields(result);

for(int i=0;i<num;i++){
printf("%s \t",fields[i].name);//打印列名
}

获取当前字符集与设置字符集

1
2
3
4
5
6
7
const char* mysql_character_set_name(MYSQL* mysql);
//获取字符集

//设置字符集
mysql_set_character_set(mysql,"utf8");
//或者
mysql_query(mysql,"set names utf8");

实例 简单的模拟mysql客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mysql/mysql.h>

int main(){

//1 初始化

MYSQL *conn = mysql_init(NULL);
if(conn == NULL){
printf("init error\n");
exit(-1);
}

//2 连接

conn = mysql_real_connect(conn,"localhost","root","asdf","mytest",0,NULL,0);
if(conn == NULL){
printf("mysql connect error : [%s]\n",mysql_error(conn));
exit(-1);
}

//3 设置字符集
int ret = mysql_set_character_set(conn,"utf8");
if(ret == -1){
printf("mysql connect error : [%s]\n",mysql_error(conn));
exit(-1);
}

//4 循环
while(1){
write(STDOUT_FILENO,"mysql> ",sizeof("mysql> "));//无缓冲

// 读取用户输入
char buf[1024] = {0};
read(STDIN_FILENO,buf,sizeof(buf));


// 如果是exit 或者 quit 则退出
if(strncasecmp(buf,"quit",4) == 0 || strncasecmp(buf,"exit",4) == 0){
write(STDOUT_FILENO,"Bye\n",sizeof("Bye\n"));
mysql_close(conn);
return 0;
}

if(strncasecmp(buf,"select",6) != 0){
//不是select查询
//那就是普通的更新或者其他语句
int ret = mysql_query(conn,buf);
if(ret != 0){
printf("mysql query error : [%s]\n",mysql_error(conn));
continue;
}
int len = mysql_affected_rows(conn);
printf("Query OK, %d row affected\n",len);
}else{
//是select
int ret = mysql_query(conn,buf);
if(ret != 0){
printf("mysql query error : [%s]\n",mysql_error(conn));
continue;
}

//获得结果集
MYSQL_RES * result = mysql_store_result(conn);
if(result == NULL){
printf("mysql query error : [%s]\n",mysql_error(conn));
continue;
}

//获取列数,打印列名
int columns = mysql_num_fields(result);

MYSQL_FIELD * fields = mysql_fetch_fields(result);

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

//打印结果集合
MYSQL_ROW row;
while(row = mysql_fetch_row(result)){
for(int i = 0;i<columns;i++){
printf("%s\t",row[i]);
}
printf("\n");
}

//释放结果集
mysql_free_result(result);
}
}

//关闭连接
mysql_close(conn);
return 0;
}
  • 没有对分号进行处理,所以不要加分号。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!