目录
1,连接查询
2,视图
3,联集
4,case
5,日期时间函数
6,空值和无值
7,regexp正则表达式
8,运算符
9,存储过程
10,常见的错误代码
11,死锁
1,连接查询
inner join on(内连接)只返回两个表中联结字段的相等的行 left join on(左连接): 返回包括左表中的所有记录和右表中联结字段相等的记录 right join on(右连接): 返回包括右表中的所有记录和左表中联结字段相等的记录
语法: select 字段 from 表1 inner join 表2 on 条件 select 字段 from 表1 left join 表2 on 条件 select 字段 from 表1 right join 表2 on 条件
例;
环境两张表
(root@localhost) [hellodb]> select *from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 33 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 18 | Hua Rong | 23 | M | 7 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
(root@localhost) [hellodb]> select *from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
+-----+---------------+-----+--------+
4 rows in set (0.00 sec)
内连接:
(root@localhost) [hellodb]> select *from teachers inner join students on
students.teacherid=teachers.tid; ##显示 teacher表的所有字段,采用内连接要求teacgerid=tid
+-----+---------------+-----+--------+-------+-------------+-----+--------+---------+-----------+
| TID | Name | Age | Gender | StuID | Name | Age | Gender | ClassID | TeacherID |
+-----+---------------+-----+--------+-------+-------------+-----+--------+---------+-----------+
| 3 | Miejue Shitai | 77 | F | 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 4 | Lin Chaoying | 93 | F | 4 | Ding Dian | 32 | M | 4 | 4 |
| 1 | Song Jiang | 45 | M | 5 | Yu Yutong | 26 | M | 3 | 1 |
+-----+---------------+-----+--------+-------+-------------+-----+--------+---------+-----------+
3 rows in set (0.00 sec)
可以采用别名
(root@localhost) [hellodb]> select *from teachers t inner join studentts s
on s.teacherid=t.tid;
+-----+---------------+-----+--------+-------+-------------+-----+--------+---------+-----------+
| TID | Name | Age | Gender | StuID | Name | Age | Gender | ClassID | TeacherID |
+-----+---------------+-----+--------+-------+-------------+-----+--------+---------+-----------+
| 3 | Miejue Shitai | 77 | F | 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 4 | Lin Chaoying | 93 | F | 4 | Ding Dian | 32 | M | 4 | 4 |
| 1 | Song Jiang | 45 | M | 5 | Yu Yutong | 26 | M | 3 | 1 |
+-----+---------------+-----+--------+-------+-------------+-----+--------+---------+-----------+
3 rows in set (0.00 sec)
左连接
(root@localhost) [hellodb]> select *from teachers t left join studentss s
on s.teacherid=t.tid; ##左连接显示teachers表所有字段和students表中符合要求的字段
+-----+---------------+-----+--------+-------+-------------+------+--------+---------+-----------+
| TID | Name | Age | Gender | StuID | Name | Age | Gender | ClassID | TeacherID |
+-----+---------------+-----+--------+-------+-------------+------+--------+---------+-----------+
| 3 | Miejue Shitai | 77 | F | 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 4 | Lin Chaoying | 93 | F | 4 | Ding Dian | 32 | M | 4 | 4 |
| 1 | Song Jiang | 45 | M | 5 | Yu Yutong | 26 | M | 3 | 1 |
| 2 | Zhang Sanfeng | 94 | M | NULL | NULL | NULL | NULL | NULL | NULL |
+-----+---------------+-----+--------+-------+-------------+------+--------+---------+-----------+
4 rows in set (0.00 sec)
右连接
(root@localhost) [hellodb]> select *from teachers t right join studentts s
on s.teacherid=t.tid; #显示teachers表中符合要求的字段和students表中所有字段
+------+---------------+------+--------+-------+---------------+-----+--------+---------+-----------+
| TID | Name | Age | Gender | StuID | Name | Age | Gender | ClassID | TeacherID |
+------+---------------+------+--------+-------+---------------+-----+--------+---------+-----------+
| 1 | Song Jiang | 45 | M | 5 | Yu Yutong | 26 | M | 3 | 1 |
| 3 | Miejue Shitai | 77 | F | 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 4 | Lin Chaoying | 93 | F | 4 | Ding Dian | 32 | M | 4 | 4 |
| NULL | NULL | NULL | NULL | 2 | Shi Potian | 22 | M | 1 | 7 |
| NULL | NULL | NULL | NULL | 3 | Xie Yanke | 53 | M | 2 | 16 |
| NULL | NULL | NULL | NULL | 6 | Shi Qing | 46 | M | 5 | NULL |
| NULL | NULL | NULL | NULL | 7 | Xi Ren | 19 | F | 3 | NULL |
| NULL | NULL | NULL | NULL | 8 | Lin Daiyu | 17 | F | 7 | NULL |
| NULL | NULL | NULL | NULL | 9 | Ren Yingying | 20 | F | 6 | NULL |
| NULL | NULL | NULL | NULL | 10 | Yue Lingshan | 19 | F | 3 | NULL |
| NULL | NULL | NULL | NULL | 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| NULL | NULL | NULL | NULL | 12 | Wen Qingqing | 19 | F | 1 | NULL |
| NULL | NULL | NULL | NULL | 13 | Tian Boguang | 33 | M | 2 | NULL |
| NULL | NULL | NULL | NULL | 14 | Lu Wushuang | 17 | F | 3 | NULL |
| NULL | NULL | NULL | NULL | 15 | Duan Yu | 19 | M | 4 | NULL |
| NULL | NULL | NULL | NULL | 16 | Xu Zhu | 21 | M | 1 | NULL |
| NULL | NULL | NULL | NULL | 17 | Lin Chong | 25 | M | 4 | NULL |
| NULL | NULL | NULL | NULL | 18 | Hua Rong | 23 | M | 7 | NULL |
| NULL | NULL | NULL | NULL | 19 | Xue Baochai | 18 | F | 6 | NULL |
| NULL | NULL | NULL | NULL | 20 | Diao Chan | 19 | F | 7 | NULL |
| NULL | NULL | NULL | NULL | 21 | Huang Yueying | 22 | F | 6 | NULL |
| NULL | NULL | NULL | NULL | 22 | Xiao Qiao | 20 | F | 1 | NULL |
| NULL | NULL | NULL | NULL | 23 | Ma Chao | 23 | M | 4 | NULL |
| NULL | NULL | NULL | NULL | 24 | Xu Xian | 27 | M | NULL | NULL |
| NULL | NULL | NULL | NULL | 25 | Sun Dasheng | 100 | M | NULL | NULL |
+------+---------------+------+--------+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
2,视图
---- CREATE VIEW ----视图,可以被当作是虚拟表或 存储查询结果的表。 视图跟表格的不同是,表格中有实际储存资料,而视图是建立在表格之上的一个架构,它本身并不实际储存资料。
临时表在用户退出出或同步数据库的连接断开后就自动消失了,而视图不会消失。视图不含有数据,只存储它的定义,它的用途一般可以简化复杂的查询。 比如你要对几个表进行连接查询,而且还要进行统计排序等操作,写SQL语句会很麻烦的, 用视图将几个表联结起来,然后对这个视图进行查询操作,就和对一个表查询一样,很方便。
语法: create view “视图表名” as select 语句;
例:
(root@localhost) [hellodb]> create view v_info as select t.name from teachers t
inner join students s on s.teacherid=t.tid; ##创建视图
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [hellodb]> show tables; ##查看表视图创建成功
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| students |
| teachers |
| test1 |
| test2 |
| toc |
| v_info |
+-------------------+
10 rows in set (0.00 sec)
(root@localhost) [hellodb]> select *from v_info; ##查看视图
+---------------+
| name |
+---------------+
| Miejue Shitai |
| Lin Chaoying |
| Song Jiang |
+---------------+
3 rows in set (0.00 sec)
(root@localhost) [hellodb]> drop view v_info; ##删除视图
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [hellodb]> show tables; ##查看删除成功
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| students |
| teachers |
| test1 |
| test2 |
| toc |
+-------------------+
9 rows in set (0.00 sec)
3,联集
---- UNION ---- 联集,将两个sQL语句的结果合并起来,两个sqL语句所产生的字段需要是同样的数据类型; UNION:生成结果的资料值将没有重复,且按照字段的顺序进行排序 语法:select 语句1 union select 语句2
select 语句1 union all select 语句2
(root@localhost) [hellodb]> select * from teachers union select stuid,name,
age,gender from students; ##合并两张表
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |teachers
| 1 | Shi Zhongyu | 22 | M |students
| 2 | Shi Potian | 22 | M |
| 3 | Xie Yanke | 53 | M |
| 4 | Ding Dian | 32 | M |
| 5 | Yu Yutong | 26 | M |
| 6 | Shi Qing | 46 | M |
| 7 | Xi Ren | 19 | F |
| 8 | Lin Daiyu | 17 | F |
| 9 | Ren Yingying | 20 | F |
| 10 | Yue Lingshan | 19 | F |
| 11 | Yuan Chengzhi | 23 | M |
| 12 | Wen Qingqing | 19 | F |
| 13 | Tian Boguang | 33 | M |
| 14 | Lu Wushuang | 17 | F |
| 15 | Duan Yu | 19 | M |
| 16 | Xu Zhu | 21 | M |
| 17 | Lin Chong | 25 | M |
| 18 | Hua Rong | 23 | M |
| 19 | Xue Baochai | 18 | F |
| 20 | Diao Chan | 19 | F |
| 21 | Huang Yueying | 22 | F |
| 22 | Xiao Qiao | 20 | F |
| 23 | Ma Chao | 23 | M |
| 24 | Xu Xian | 27 | M |
| 25 | Sun Dasheng | 100 | M |
+-----+---------------+-----+--------+
29 rows in set (0.00 sec)
(root@localhost) [hellodb]> select * from teachers union select name ,
stuid,age,gender from students; ##合并时,字段要按字段顺序写
ERROR 1054 (42S22): Unknown column 'name,stuid' in 'field list'
4,case
是sql 用来 作为 if-then-else 之类的关键字 语法: select? 需要显示的字段名1 '可以自定义', 需要显示的字段名2 '可以自定义', case? when 条件1 then 结果1 when 条件2 then 结果2 else? end '显示结果的字段名' 条件可以是一个 数值 或是公式 else 子句 不是必须的
例:
(root@localhost) [hellodb]> select name'名字',age'年龄',case when age<18 then '未成年'
when age <60 then '成年' else '老年' end '是否成年'' from students;
+---------------+--------+--------------+ ##字段后面可以自定义名字
| 名字 | 年龄 | 是否成年 | ##end后是加的字段的名字
+---------------+--------+--------------+
| Shi Zhongyu | 22 | 成年 |
| Shi Potian | 22 | 成年 |
| Xie Yanke | 53 | 成年 |
| Ding Dian | 32 | 成年 |
| Yu Yutong | 26 | 成年 |
| Shi Qing | 46 | 成年 |
| Xi Ren | 19 | 成年 |
| Lin Daiyu | 17 | 未成年 |
| Ren Yingying | 20 | 成年 |
| Yue Lingshan | 19 | 成年 |
| Yuan Chengzhi | 23 | 成年 |
| Wen Qingqing | 19 | 成年 |
| Tian Boguang | 33 | 成年 |
| Lu Wushuang | 17 | 未成年 |
| Duan Yu | 19 | 成年 |
| Xu Zhu | 21 | 成年 |
| Lin Chong | 25 | 成年 |
| Hua Rong | 23 | 成年 |
| Xue Baochai | 18 | 成年 |
| Diao Chan | 19 | 成年 |
| Huang Yueying | 22 | 成年 |
| Xiao Qiao | 20 | 成年 |
| Ma Chao | 23 | 成年 |
| Xu Xian | 27 | 成年 |
| Sun Dasheng | 100 | 老年 |
+---------------+--------+--------------+
25 rows in set (0.00 sec)
5,日期时间函数
字符串函数 | 描述 |
---|
curdate() | 返回当前时间的年月日 | curtime() | 返回当前时间的时分秒 | now() | 返回当前时间的日期和时间 | month(x) | 返回日期 x 中的月份值 | week(x) | 返回日期 x 是年度第几个星期 | hour(x) | 返回 x 中的小时值 | minute(x) | 返回 x 中的分钟值 | second(x) | 返回 x 中的秒钟值 | dayofweek(x) | 返回 x 是星期几,1 星期日,2 星期一 | dayofmonth(x) | 计算日期 x 是本月的第几天 | dayofyear(x) | 计算日期 x 是本年的第几天 |
例:
(root@localhost) [hellodb]> select curdate();
+------------+ ##当前日期
| curdate() |
+------------+
| 2021-12-06 |
+------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select curtime();
+-----------+ ##当前时间
| curtime() |
+-----------+
| 05:37:14 |
+-----------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select now();
+---------------------+ ##当前的日期和时间
| now() |
+---------------------+
| 2021-12-06 05:37:24 |
+---------------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select month(curdate());
+------------------+ ##当前时间的月份
| month(curdate()) |
+------------------+
| 12 |
+------------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select week(now());
+-------------+ ##当前时间的一年第多少周
| week(now()) |
+-------------+
| 49 |
+-------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select hour(now());
+-------------+ ##当前时间一天第几个小时
| hour(now()) |
+-------------+
| 5 |
+-------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select minute(now());
+---------------+ ##当前时间当前小时第多少分钟
| minute(now()) |
+---------------+
| 39 |
+---------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select second(now());
+---------------+ ##当前分钟第多少秒
| second(now()) |
+---------------+
| 58 |
+---------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select dayofweek(curdate());
+----------------------+ ##当前周第几天(周日为第一天)
| dayofweek(curdate()) |
+----------------------+
| 2 |
+----------------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select dayofmonth(curdate());
+-----------------------+ ##当前时间是这月的第几天
| dayofmonth(curdate()) |
+-----------------------+
| 6 |
+-----------------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select dayofyear(curdate());
+----------------------+ ##当前时间是这一年的第几天
| dayofyear(curdate()) |
+----------------------+
| 340 |
+----------------------+
1 row in set (0.00 sec)
6,空值和无值
NULL 值和空值有什么区别呢?二者的区别如下: 空值的长度为 0,不占用空间的;而 NULL 值的长度是 NULL,是占用空间的。 IS NULL 或者 IS ?NOT NULL,是用来判断字段是不是为 NULL 或者不是 NULL,不能查出是不是空值的。 空值的判断使用=’’或者<>’’来处理。 在通过 count()计算有多少记录数时,如果遇到 NULL 值会自动忽略掉,遇到空值会加入到记录中进行计算。
例
(root@localhost) [hellodb]> select length(null),length(' '),length('abc');
+--------------+-------------+---------------+
| length(null) | length(' ') | length('abc') |
+--------------+-------------+---------------+
| NULL | 1 | 3 |
+--------------+-------------+---------------+
1 row in set (0.00 sec)
##所占字符数
7,regexp正则表达式
匹配模式 | 描述 | 实例 |
---|
^ | 匹配文本的开始字符 | ‘^bd’ 匹配以 bd 开头的字符串 | $ | 匹配文本的结束字符 | ‘qn$’ 匹配以 qn 结尾的字符串 | . | 匹配任何单个字符 | ‘s.t’ 匹配任何s 和t 之间有一个字符的字符串 | * | 匹配零个或多个在它前面的字符 | ‘fo*t’ 匹配 t 前面有任意个 o | + | 匹配前面的字符 1 次或多次 | ‘hom+’ 匹配以 ho 开头,后面至少一个m 的字符串 | 字符串 | 匹配包含指定的字符串 | ‘clo’ 匹配含有 clo 的字符串 | p1|p2 | 匹配 p1 或 p2 | ‘bg|fg’ 匹配 bg 或者 fg | [...] | 匹配字符集合中的任意一个字符 | ‘[abc]’ 匹配 a 或者 b 或者 c | [^...] | 匹配不在括号中的任何字符 | [^ab] 匹配不包含 a 或者 b 的字符串 | {n} | 匹配前面的字符串 n 次 | ‘g{2}’ 匹配含有 2 个 g 的字符串 | {n,m} | 匹配前面的字符串至少 n 次,至多m 次 | f{1,3}’ 匹配 f 最少 1 次,最多 3 次 |
例:
(root@localhost) [hellodb]> select *from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
+-----+---------------+-----+--------+
4 rows in set (0.01 sec)
(root@localhost) [hellodb]> select tid,name from teachers where name regexp '^s';
+-----+------------+ ##名字以s开头的老师
| tid | name |
+-----+------------+
| 1 | Song Jiang |
+-----+------------+
1 row in set (0.01 sec)
(root@localhost) [hellodb]> select tid,name from teachers where name regexp 'i$';
+-----+---------------+ ##名字以i结尾的老师
| tid | name |
+-----+---------------+
| 3 | Miejue Shitai |
+-----+---------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select tid,name from teachers where name regexp 'en';
+-----+---------------+ ##名字中包含en的老师
| tid | name |
+-----+---------------+
| 2 | Zhang Sanfeng |
+-----+---------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select tid,name from teachers where name regexp 'miej.e';
+-----+---------------+ ##名字以miej中间不知道是什么后面是e的老师
| tid | name |
+-----+---------------+
| 3 | Miejue Shitai |
+-----+---------------+
1 row in set (0.00 sec)
(root@localhost) [hellodb]> select tid,name from teachers where name regexp 'en|an';
+-----+---------------+ ##名字中有en或者an的老师
| tid | name |
+-----+---------------+
| 1 | Song Jiang |
| 2 | Zhang Sanfeng |
+-----+---------------+
2 rows in set (0.00 sec)
(root@localhost) [hellodb]> select tid,name from teachers where name regexp '^[a-y]';
+-----+---------------+ #名字以a-y开头的老师
| tid | name |
+-----+---------------+
| 1 | Song Jiang |
| 3 | Miejue Shitai |
| 4 | Lin Chaoying |
+-----+---------------+
3 rows in set (0.00 sec)
(root@localhost) [hellodb]> select tid,name from teachers where name regexp '^[^a-y]';
+-----+---------------+ #名字不以a-y开头的老师
| tid | name |
+-----+---------------+
| 2 | Zhang Sanfeng |
+-----+---------------+
1 row in set (0.00 sec)
8,运算符
1、算术运算符 以 SELECT 命令来实现最基础的加减乘除运算,MySQL 支持使用的算术运算符,
+?? ??? ?加法 -?? ??? ?减法 *?? ??? ?乘法 /?? ??? ?除法 %?? ??? ?取余
例:
?
(root@localhost) [hellodb]> select 2+5,5-2,2*5,2/5,5%2;
+-----+-----+-----+--------+------+
| 2+5 | 5-2 | 2*5 | 2/5 | 5%2 |
+-----+-----+-----+--------+------+
| 7 | 3 | 10 | 0.4000 | 1 |
+-----+-----+-----+--------+------+
1 row in set (0.01 sec)
9,存储过程
使用方法 是shell脚本
格式和函数很像
MySQL 数据库存储过程是一组为了完成特定功能的 SQL 语句的集合 存储过程在使用过程中是将常用或者复杂的工作预先使用 SQL 语句写好并用一个指定的名称存储起来, 这个过程经编译和优化后存储在数据库服务器中。当需要使用该存储过程时,只需要调用它即可。 存储过程在执行上比传统sql速度更快、执行效率更高。
存储过程的优势
-
封装性 通常完成一个逻辑功能需要多条 SQL 语句,而且各个语句之间很可能传递参数,所以,编写逻辑功能相对来说稍微复杂些,而存储过程可以把这些 SQL 语句包含到一个独立的单元中,使外界看不到复杂的 SQL 语句,只需要简单调用即可达到目的。并且数据库专业人员可以随时对存储过程进行修改,而不会影响到调用它的应用程序源代码 -
可增强 SQL 语句的功能和灵活性 存储过程可以用流程控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。 -
可减少网络流量 由于存储过程是在服务器端运行的,且执行速度快,因此当客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而可降低网络负载。 -
提高性能 当存储过程被成功编译后,就存储在数据库服务器里了,以后客户端可以直接调用,这样所有的 SQL 语句将从服务器执行,从而提高性能。但需要说明的是,存储过程不是越多越好,过多的使用存储过程反而影响系统性能 -
提高数据库的安全性和数据的完整性 存储过程提高安全性的一个方案就是把它作为中间组件,存储过程里可以对某些表做相关操作,然后存储过程作为接口提供给外部程序。这样,外部程序无法直接操作数据库表,只能通过存储过程来操作对应的表,因此在一定程度上,安全性是可以得到提高的。 -
使数据独立 数据的独立可以达到解耦的效果,也就是说,程序可以调用存储过程,来替代执行多条的 SQL 语句。这种情况下,存储过程把数据同用户隔离开来,优点就是当数据表的结构改变时,调用表不用修改程序,只需要数据库管理者重新编写存储过程即可。
语法: CREATE PROCEDURE <存储过程名> ( [过程参数[,…] ] ) <过程体> [过程参数[,…] ] 格式 <过程名>:尽量避免与内置的函数或字段重名 <过程体>:语句 [ IN | OUT | INOUT ] <参数名><类型>
1) 过程名 存储过程的名称,默认在当前数据库中创建。若需要在特定数据库中创建存储过程,则要在名称前面加上数据库的名称,即 db_name.sp_name。 需要注意的是,名称应当尽量避免选取与 MySQL 内置函数相同的名称,否则会发生错误。
2) 过程参数 存储过程的参数列表。其中,<参数名>为参数名,<类型>为参数的类型(可以是任何有效的 MySQL 数据类型)。当有多个参数时,参数列表中彼此间用逗号分隔。存储过程可以没有参数(此时存储过程的名称后仍需加上一对括号),也可以有 1 个或多个参数。 MySQL 存储过程支持三种类型的参数,即输入参数、输出参数和输入/输出参数,分别用 IN、OUT 和 INOUT 三个关键字标识。其中,输入参数可以传递给一个存储过程,输出参数用于存储过程需要返回一个操作结果的情形,而输入/输出参数既可以充当输入参数也可以充当输出参数。
3) 过程体 存储过程的主体部分,也称为存储过程体,包含在过程调用的时候必须执行的 SQL 语句。这个部分以关键字 BEGIN 开始,以关键字 END 结束 在 MySQL 中,服务器处理 SQL 语句默认是以分号作为语句结束标志的。然而,在创建存储过程时,存储过程体可能包含有多条 SQL 语句,这些 SQL 语句如果仍以分号作为语句结束符,那么 MySQL 服务器在处理时会以遇到的第一条 SQL 语句结尾处的分号作为整个程序的结束符,而不再去处理存储过程体中后面的 SQL 语句,这样显然不行。 为解决以上问题,通常使用 DELIMITER 命令将结束命令修改为其他字符。语法格式如下: delimiter $$ 语法说明如下: $$ 是用户定义的结束符,通常这个符号可以是一些特殊的符号,如两个“?”或两个“¥”等。 当使用 DELIMITER 命令时,应该避免使用反斜杠“\”字符,因为它是 MySQL 的转义字符
成功执行这条 SQL 语句后,任何命令、语句或程序的结束标志就换为两个?? mysql > DELIMITER ?? 若希望换回默认的分号“;”作为结束标志,则在 MySQL 命令行客户端输入下列语句即可 mysql > DELIMITER ; 注意:DELIMITER 和分号“;”之间一定要有一个空格
delimiter ?? CREATE PROCEDURE 存储过程名()?? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BEGIN?? ??? ??? ??? ? 执行的sql语句 1 ; 执行的sql语句 2 ; end ??
delimiter(一定要加空格,一定要加空格,一定要加空格);
call 存储过程名
例:(不带参数的创建)
(root@localhost) [hellodb]> delimiter $$ ##两个$$可以自定义将结束符号设为$$
(root@localhost) [hellodb]> create procedure data() ##创建存储过程
-> begin ##以begin开始
-> create table book (id int (10), name char(10),age int (10)); #SQL语句
-> insert into book values (1,'lili',18);
-> select * from book;
-> end $$ ##过程体以end结束
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [hellodb]> delimiter ; ##将结束符号改回;
(root@localhost) [hellodb]> call data; ##查看存储过程call 过程名
+------+------+------+
| id | name | age |
+------+------+------+
| 1 | lili | 18 |
+------+------+------+
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
(root@localhost) [hellodb]> delimiter //
(root@localhost) [hellodb]> create procedure del()
-> begin
-> select curdate();
-> end //
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [hellodb]> delimiter ;
(root@localhost) [hellodb]> call del;
+------------+
| curdate() |
+------------+
| 2021-12-06 |
+------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
带参数的创建
(root@localhost) [hellodb]> delimiter %% ##结束符号可以自定义
(root@localhost) [hellodb]> create procedure proc1(in inname varchar(30))
-> begin
-> select * from teachers where name=inname;
-> end %%
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [hellodb]> delimiter ;
(root@localhost) [hellodb]> call proc1('song jiang');
+-----+------------+-----+--------+
| TID | Name | Age | Gender |
+-----+------------+-----+--------+
| 1 | Song Jiang | 45 | M |
+-----+------------+-----+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
条件判断 if then else ? ..... end if delimiter $$ create procedure ?proc6(in var int) begin if var>10 then update students set age=age+1 where stuid=1; end if; end $$ ? delimiter ; call proc(11)
循环 while do....end while
create table testlog (id int auto_increment primary key,name char(10),age int default 20);
delimiter $$
create procedure ?ky15()? begin ? declare i int; set i = 1;? while i <= 100000? do ?insert into testlog(name,age) values (concat('zhou',i),i);? set i = i +1;? end while;? end$$
delimiter ;
select concat(zhou,1); select * from testlog limit 10;
查看存储过程
格式: SHOW CREATE PROCEDURE [数据库.]存储过程名;?? ?
(root@localhost) [hellodb]> call del;
+------------+
| curdate() |
+------------+
| 2021-12-06 |
+------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [hellodb]> call proc1('song jiang');
+-----+------------+-----+--------+
| TID | Name | Age | Gender |
+-----+------------+-----+--------+
| 1 | Song Jiang | 45 | M |
+-----+------------+-----+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
删除存储过程
##删除存储过程## 存储过程内容的修改方法是通过删除原有存储过程,之后再以相同的名称创建新的存储过程。
DROP PROCEDURE IF EXISTS Proc;
(root@localhost) [hellodb]> drop procedure if exists del;
Query OK, 0 rows affected (0.01 sec)
(root@localhost) [hellodb]> call del;
ERROR 1305 (42000): PROCEDURE hellodb.del does not exist
10,常见的错误代码
常见的服务器错误代码及说明如下表所示:
错误代码 | 说 明 |
---|
1004 | 无法创建文件 | 1005 | 无法创建数据表、创建表失败 | 1006 | 无法创建数据库、创建数据库失败 | 1007 | 无法创建数据库,数据库己存在 | 1008 | 无法删除数据库,数据库不存在 | 1009 | 不能删除数据库文件导致删除数据库失败 | 1010 | 不能删除数据目录导致删除数据库失败 | 1011 | 删除数据库文件时出错 | 1012 | 无法读取系统表中的记录 | 1013 | 无法获取的状态 | 1014 | 无法获得工作目录 | 1015 | 无法锁定文件 | 1016 | 无法打开文件 | 1017 | 无法找到文件 | 1018 | 无法读取的目录 | 1019 | 无法为更改目录 | 1020 | 记录已被其它用户修改 | 1021 | 硬盘剩余空间不足,请加大硬盘可用空间 | 1022 | 关键词重读,更改记录失败 | 1023 | 关闭时发生错误 | 1025 | 更改名字时发生错误 | 1032 | 记录不存在 | 1036 | 数据表是只读的,不能对它进行修改 | 1037 | 系统内存不足,请重启数据库或重启服务器 | 1042 | 无效的主机名 | 1044 | 当前用户没有访问数据库的权限 | 1045 | 不能连接数据库,用户名或密码错误 |
常见的客户端错误代码及说明如下所示:
2000 | 未知 MySQL 错误 |
---|
2001 | 不能创建 UNIX 套接字(%d) | 2002 | 不能通过套接字“ %s”(%d)连接到本地 MySQL 服务器, self 服务未启动 | 2003 | 不能连接到 %s ”(%d )上的 MySQL 服务器,未启动 mysql 服务 | 2004 | 不能创建 TCP/IP 接字(%d) | 2005 | 未知的 MySQL 服务器主机“ %s”(%d) | 2007 | 协议不匹配,服务器版本=%d,客户端版本=%d | 2008 | MySQL 客户端内存溢出 | 2009 | 错误的主机信息 | 2010 | 通过 UNIX 套接字连接的本地主机 | 2012 | 服务器握手过程中出错 | 2013 | 查询过程中丢失了与 SQL 服务器的连接 | 2014 | 命令不同步,现在不能运行该命令 | 2024 | 连接到从服务器时出错 | 2025 | 连接到主服务器时出错 | 2026 | SSL 连接错误 |
11,死锁
死锁:是指两个或两个以上的事务在执行过程中,因争夺资源而造成的一种互相等待的现象。就是所谓的锁资源请求产生了回路现象,即死循环,此时称系统处于死锁状态或系统产生了死锁。常见的报错信息为“Deadlock found when trying to get lock...”。
在实际应用中,我们要尽量防止死锁等待现象的发生,下面介绍几种避免死锁的方法:
-
如果不同程序会并发存取多个表,或者涉及多行记录时,尽量约定以相同的顺序访问表,这样可以大大降低死锁的发生。 -
业务中要及时提交或者回滚事务,可减少死锁产生的概率。 -
在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率。 -
对于非常容易产生死锁的业务部分,可以尝试使用升级锁粒度,通过表锁定来减少死锁产生的概率(表级锁不会产生死锁)。
|