Java教程

SQL高级语言(二)

本文主要是介绍SQL高级语言(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

别名        

 子查询

exists

连接查询

视图

联集

case

日期时间函数

空值和无值

regexp正则表达式

 存储过程

死锁

        常见的错误代码


别名        

        在 MySQL 查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者,多次使用相同的表,可以给字段列或表设置别名。使用的时候直接使用别名,简洁明了,增强可读性

语法:
对于字段的别名:
select 原字段 as 修改字段,原字段 as 修改字段 from 表名 ;

#as 可以省略。

例子:

(root@localhost) [jianghu]> select name as n,classid as c from Dragon;

#对于列的别名

        如果表的长度比较长,可以使用 AS 给表设置别名,在查询的过程中直接使用别名临时设置表的别名为其他

对于表的别名:
select 表格别名.原字段 as 修改字段[,表格别名.原字段 as 修改字段]from 原表名 as 表格别名 ;
#as可以省略

(root@localhost) [jianghu]> select d.name as n ,d.classid as c from Dragon d;


将聚合函数字段 设置成平均值 

(root@localhost) [jianghu]> select *,avg(age) '平均值' from Dragon;
+-----+-----------+------+--------+--------------+---------+-----------+
| Did | Name      | Age  | Gender | MasterId     | ClassId | 平均值    |
+-----+-----------+------+--------+--------------+---------+-----------+
|   1 | 风清扬    |   56 | 男     | 独孤求败     |       1 |   35.1905 |
+-----+-----------+------+--------+--------------+---------+-----------+
1 row in set (0.01 sec)

使用场景:
1、对复杂的表进行查询的时候,别名可以缩短查询语句的长度
2、多表相连查询的时候(通俗易懂、减短sql语句长度)

        此外,AS 还可以作为连接语句的操作符。
        创建t1表,将Dragon表的查询记录全部插入test1表

#可以使用as直接创建,不继承 特殊键

create table test2 (select * from Dragon);

(root@localhost) [jianghu]> create table test1 as select * from Dragon;
Query OK, 21 rows affected (0.02 sec)
Records: 21  Duplicates: 0  Warnings: 0

继承特殊键 

(root@localhost) [jianghu]> create table test3 like Dragon;
Query OK, 0 rows affected (0.01 sec)

 子查询

        子查询也被称作内查询或者嵌套查询,是指在一个查询语句里面还嵌套着另一个查询语句。
        子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一 步的查询过滤。
        子查询:在SQL语句嵌套着查询语句,性能较差,基于某语句的查询结果再次进行的查询
语法:
select 字段 from 表1 where 字段2 [比较运算符] (select 字段1 from 表格2 where 条件)
#比较运算符 可以是 =  >  <  >= <= 也可以是文字运算符 like in between

例子:

同一张表中

(root@localhost) [jianghu]> select * from Dragon where age in (select age from Dragon where age>30);
+-----+--------------+------+--------+--------------+---------+
| Did | Name         | Age  | Gender | MasterId     | ClassId |
+-----+--------------+------+--------+--------------+---------+
|   1 | 风清扬       |   56 | 男     | 独孤求败     |       1 |
|   2 | 萧远山       |   34 | 男     | 2            |       3 |
|   5 | 张三丰       |  100 | 男     | 2            |       1 |
|  10 | 独孤求败     |   66 | 男     | 1            |       1 |
|  11 | 郭靖         |   33 | 男     | 2            |       5 |
|  20 | xxx          |   50 | 男     | 2            |       1 |
|  21 | xxx          |   50 | 男     | null         |       1 |
|  22 | xxx          |   50 | 男     | NULL         |    NULL |
+-----+--------------+------+--------+--------------+---------+
8 rows in set (0.00 sec)

不同表 

Dragon表

(root@localhost) [jianghu]> select * from Dragon;
+-----+--------------+------+--------+--------------+---------+
| Did | Name         | Age  | Gender | MasterId     | ClassId |
+-----+--------------+------+--------+--------------+---------+
|   1 | 风清扬       |   56 | 男     | 独孤求败     |       1 |
|   2 | 萧远山       |   34 | 男     | 2            |       3 |
|   3 | 东方不败     |   25 | 女     | 7            |       2 |
|   4 | 萧峰         |   21 | 男     | 6            |       3 |
|   5 | 张三丰       |  100 | 男     | 2            |       1 |
|   6 | 令狐冲       |   25 | 男     | 3            |       2 |
|   7 | 杨过         |   18 | 男     | 3            |       3 |
|   8 | 小龙女       |   20 | 女     | 3            |       3 |
|   9 | 张无忌       |   27 | 男     | 1            |       8 |
|  10 | 独孤求败     |   66 | 男     | 1            |       1 |
|  11 | 郭靖         |   33 | 男     | 2            |       5 |
|  12 | 黄蓉         |   25 | 女     | 2            |       5 |
|  13 | 胡一刀       |   21 | 男     | 3            |       8 |
|  14 | 袁承志       |   19 | 男     | 5            |       3 |
|  15 | 虚竹         |   19 | 男     | 3            |       1 |
|  16 | 石破天       |   24 | 男     | 1            |       1 |
|  17 | 段誉         |   28 | 男     | 1            |       1 |
|  18 | 阿青         |   28 | 女     | 3            |       5 |
|  20 | xxx          |   50 | 男     | 2            |       1 |
|  21 | xxx          |   50 | 男     | null         |       1 |
|  22 | xxx          |   50 | 男     | NULL         |    NULL |
+-----+--------------+------+--------+--------------+---------+
21 rows in set (0.00 sec)

one_db表

(root@localhost) [jianghu]> select * from one_db;
+----+--------------+------+--------+-------+
| id | name         | age  | Gender | oneid |
+----+--------------+------+--------+-------+
|  1 | 陆小凤       |   26 | 男     |     2 |
|  2 | 西门吹雪     |   28 | 男     |     3 |
|  3 | 楚留香       |   28 | 男     |    18 |
|  4 | 李寻欢       |   28 | 男     |    15 |
|  5 | 木道人       |   56 | 男     |     6 |
|  6 | 沈浪         |   30 | 男     |     8 |
+----+--------------+------+--------+-------+
6 rows in set (0.00 sec)

#显示one_db 表中 oneid小于3的

(root@localhost) [jianghu]> select * from Dragon where classid in (select oneid from one_db where oneid<3);
+-----+--------------+------+--------+----------+---------+
| Did | Name         | Age  | Gender | MasterId | ClassId |
+-----+--------------+------+--------+----------+---------+
|   3 | 东方不败     |   25 | 女     | 7        |       2 |
|   6 | 令狐冲       |   25 | 男     | 3        |       2 |
+-----+--------------+------+--------+----------+---------+
2 rows in set (0.00 sec)

计算平均年龄

(root@localhost) [jianghu]> select avg(age) from Dragon;
+----------+
| avg(age) |
+----------+
|  35.1905 |
+----------+
1 row in set (0.00 sec

找到大于平均年龄的人

(root@localhost) [jianghu]> select * from one_db where age>(select avg(age) from Dragon);
+----+-----------+------+--------+-------+
| id | name      | age  | Gender | oneid |
+----+-----------+------+--------+-------+
|  5 | 木道人    |   56 | 男     |     6 |
+----+-----------+------+--------+-------+
1 row in set (0.00 sec)

显示 Dragon 表中 name和age 字段中大于 one_db表中的平均值 

(root@localhost) [jianghu]> select name,age from Dragon where age>(select avg(age) from one_db);
+--------------+------+
| name         | age  |
+--------------+------+
| 风清扬       |   56 |
| 萧远山       |   34 |
| 张三丰       |  100 |
| 独孤求败     |   66 |
| 郭靖         |   33 |
| xxx          |   50 |
| xxx          |   50 |
| xxx          |   50 |
+--------------+------+
8 rows in set (0.00 sec)

exists

        这个关键字在子查询时,主要用于判断子查询的结果集是否为空。如果不为空, 则返回 值;反之,则返回 不存在

(root@localhost) [jianghu]> select * from Dragon where exists (select oneid from one_db where oneid<1);
Empty set (0.00 sec)

连接查询

inner join on(内连接)只返回两个表中联结字段的相等的行
left join on(左连接): 返回包括左表中的所有记录和右表中联结字段相等的记录
right join on(右连接): 返回包括右表中的所有记录和左表中联结字段相等的记录

内连接

(root@localhost) [jianghu]> (root@localhost) [jianghu]> select * from Dragon inner join one_db on Dragon.classid=one_db.oneid;
+-----+--------------+------+--------+----------+---------+----+--------------+------+--------+-------+
| Did | Name         | Age  | Gender | MasterId | ClassId | id | name         | age  | Gender | oneid |
+-----+--------------+------+--------+----------+---------+----+--------------+------+--------+-------+
|   2 | 萧远山       |   34 | 男     | 2        |       3 |  2 | 西门吹雪     |   28 | 男     |     3 |
|   3 | 东方不败     |   25 | 女     | 7        |       2 |  1 | 陆小凤       |   26 | 男     |     2 |
|   4 | 萧峰         |   21 | 男     | 6        |       3 |  2 | 西门吹雪     |   28 | 男     |     3 |
|   6 | 令狐冲       |   25 | 男     | 3        |       2 |  1 | 陆小凤       |   26 | 男     |     2 |
|   7 | 杨过         |   18 | 男     | 3        |       3 |  2 | 西门吹雪     |   28 | 男     |     3 |
|   8 | 小龙女       |   20 | 女     | 3        |       3 |  2 | 西门吹雪     |   28 | 男     |     3 |
|   9 | 张无忌       |   27 | 男     | 1        |       8 |  6 | 沈浪         |   30 | 男     |     8 |
|  13 | 胡一刀       |   21 | 男     | 3        |       8 |  6 | 沈浪         |   30 | 男     |     8 |
|  14 | 袁承志       |   19 | 男     | 5        |       3 |  2 | 西门吹雪     |   28 | 男     |     3 |
+-----+--------------+------+--------+----------+---------+----+--------------+------+--------+-------+
9 rows in set (0.00 sec)

左连接,就是左边数据全部有,右边符合条件的显示出来

(root@localhost) [jianghu]> select * from Dragon left join one_db on Dragon.classid=one_db.oneid;

右连接:右边全部数据,左边符合条件的显示出来

(root@localhost) [jianghu]> select * from Dragon right join one_db on Dragon.classid=one_db.oneid;

视图

---- CREATE VIEW ----视图,可以被当作是虚拟表或 存储查询结果的表。
#视图跟表格的不同是,表格中有实际储存资料,而视图是建立在表格之上的一个架构,它本身并不实际储存资料。

#临时表在用户退出出或同步数据库的连接断开后就自动消失了,而视图不会消失。

视图不含有数据,只存储它的定义,它的用途一般可以简化复杂的查询。
比如你要对几个表进行连接查询,而且还要进行统计排序等操作,写SQL语句会很麻烦的,
用视图将几个表联结起来,然后对这个视图进行查询操作,就和对一个表查询一样,很方便。

语法:
create view “视图表名” as select 语句;

例子:
 

(root@localhost) [jianghu]> create view v_test as select d.name from Dragon d inner join one_db o onn o.oneid=d.classid;

查看视图表
show tables;

删除视图表
drop view 视图名字

(root@localhost) [jianghu]> drop view v_test;
Query OK, 0 rows affected (0.01 sec)


视图表 本身并不实际存储数据  只是保存一个select语句查询结果

联集

---- UNION ----
        联集,将两个sQL语句的结果合并起来,两个sqL语句所产生的字段需要是同样的数据类型;
UNION:生成结果的资料值将没有重复,且按照字段的顺序进行排序
语法:select 语句1 union select 语句2

select 语句1 union all select 语句2

例子:

(root@localhost) [jianghu]> select did,name,age,Gender from Dragon union select id,name,age,Gender from one_db;
+-----+--------------+------+--------+
| did | name         | age  | Gender |
+-----+--------------+------+--------+
|   1 | 风清扬       |   56 | 男     |
|   2 | 萧远山       |   34 | 男     |
|   3 | 东方不败     |   25 | 女     |
|   4 | 萧峰         |   21 | 男     |
|   5 | 张三丰       |  100 | 男     |
|   6 | 令狐冲       |   25 | 男     |
|   7 | 杨过         |   18 | 男     |
|   8 | 小龙女       |   20 | 女     |
|   9 | 张无忌       |   27 | 男     |
|  10 | 独孤求败     |   66 | 男     |
|  11 | 郭靖         |   33 | 男     |
|  12 | 黄蓉         |   25 | 女     |
|  13 | 胡一刀       |   21 | 男     |
|  14 | 袁承志       |   19 | 男     |
|  15 | 虚竹         |   19 | 男     |
|  16 | 石破天       |   24 | 男     |
|  17 | 段誉         |   28 | 男     |
|  18 | 阿青         |   28 | 女     |
|  20 | xxx          |   50 | 男     |
|  21 | xxx          |   50 | 男     |
|  22 | xxx          |   50 | 男     |
|   1 | 陆小凤       |   26 | 男     |
|   2 | 西门吹雪     |   28 | 男     |
|   3 | 楚留香       |   28 | 男     |
|   4 | 李寻欢       |   28 | 男     |
|   5 | 木道人       |   56 | 男     |
|   6 | 沈浪         |   30 | 男     |
+-----+--------------+------+--------+
27 rows in set (0.00 sec)

注意 字段 数据类型 要一致  int和int   char和char 

case

        是sql 用来 作为 if-then-else 之类的关键字
语法:
select 
需要显示的字段名1 '可以自定义',
需要显示的字段名2 '可以自定义',
case 
when 条件1 then 结果1
when 条件2 then 结果2
else 
end '显示结果的字段名'
条件可以是一个 数值 或是公式 else 子句 不是必须的
mysql> select                      #语法
    -> name '名字',                #需要显示的字段
    -> age '年龄',                 #需要显示的字段
    -> case                       #语法
    -> when age < 18 then '少年'   #条件
    -> when age < 30 then '青年'   #条件
    -> when age < 45 then '中年'  #条件
    -> else '老年'                #条件
    -> end '状态'                 #显示结果的字段名
    -> from students;


例1:
 

(root@localhost) [jianghu]> select name, case when age<18 then '未成年' when age>=18 then '成年' endd '是否成年' from Dragon;

例2:

(root@localhost) [jianghu]> select * ,
    -> case
    -> when gender='男' then 'M'
    -> when gender='女' then 'F'
    -> end '性别'
    -> from one_db;
+----+--------------+------+--------+-------+--------+
| id | name         | age  | Gender | oneid | 性别   |
+----+--------------+------+--------+-------+--------+
|  1 | 陆小凤       |   26 | 男     |     2 | M      |
|  2 | 西门吹雪     |   28 | 男     |     3 | M      |
|  3 | 楚留香       |   28 | 男     |    18 | M      |
|  4 | 李寻欢       |   28 | 男     |    15 | M      |
|  5 | 木道人       |   56 | 男     |     6 | M      |
|  6 | 沈浪         |   30 | 男     |     8 | M      |
+----+--------------+------+--------+-------+--------+
6 rows in set (0.00 sec)

日期时间函数

字符串函数描述
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) [jianghu]> select curdate();
+------------+
| curdate()  |
+------------+
| 2021-12-04 |
+------------+
1 row in set (0.00 sec)

#当前时间的 时分秒

(root@localhost) [jianghu]> select curtime();
+-----------+
| curtime() |
+-----------+
| 19:41:33  |
+-----------+
1 row in set (0.00 sec)


#当前时间 年月日时分秒

(root@localhost) [jianghu]> select now();
+---------------------+
| now()               |
+---------------------+
| 2021-12-04 19:42:04 |
+---------------------+
1 row in set (0.00 sec)

#返回月份

(root@localhost) [jianghu]> select month('2021-12-04');
+---------------------+
| month('2021-12-04') |
+---------------------+
|                  12 |
+---------------------+
1 row in set (0.00 sec)

#返回一年中的第几个星期

(root@localhost) [jianghu]> select week('2021-12-04');
+--------------------+
| week('2021-12-04') |
+--------------------+
|                 48 |
+--------------------+
1 row in set (0.00 sec)

#返回小时值

(root@localhost) [jianghu]> select hour('2021-12-04 19:44');
+--------------------------+
| hour('2021-12-04 19:44') |
+--------------------------+
|                       19 |
+--------------------------+
1 row in set (0.00 sec)

#返回分钟的值

(root@localhost) [jianghu]> select minute('2021-12-05 14:30:9');
+------------------------------+
| minute('2021-12-05 14:30:9') |
+------------------------------+
|                           30 |
+------------------------------+
1 row in set (0.00 sec)

#返回秒值

(root@localhost) [jianghu]> select second('2021-12-04 19:45:56');
+-------------------------------+
| second('2021-12-04 19:45:56') |
+-------------------------------+
|                            56 |
+-------------------------------+
1 row in set (0.00 sec)


#返回星期几

(root@localhost) [jianghu]> select dayofweek('2021-12-04');
+-------------------------+
| dayofweek('2021-12-04') |
+-------------------------+
|                       7 |
+-------------------------+
1 row in set (0.00 sec)

#返回月中某天的值

(root@localhost) [jianghu]> select dayofmonth('2021-12-05');
+--------------------------+
| dayofmonth('2021-12-05') |
+--------------------------+
|                        5 |
+--------------------------+
1 row in set (0.00 sec)

#返回一年中的 第几天

(root@localhost) [jianghu]> select dayofyear('2021-12-05');
+-------------------------+
| dayofyear('2021-12-05') |
+-------------------------+
|                     339 |
+-------------------------+
1 row in set (0.00 sec)

空值和无值

NULL
值和空值区别如下:
空值的长度为 0,不占用空间的;而 NULL 值的长度是 NULL,是占用空间的。
IS NULL 或者 IS  NOT NULL,是用来判断字段是不是为 NULL 或者不是 NULL,不能查出是不是空值的。
空值的判断使用=’’或者<>’’来处理。
在通过 count()计算有多少记录数时,如果遇到 NULL 值会自动忽略掉,遇到空值会加入到记录中进行计算。

mysql> select length(null),length(' '),length('abc');
+--------------+-------------+---------------+
| length(null) | length(' ') | length('abc') |
+--------------+-------------+---------------+
|         NULL |           1 |             3 |
+--------------+-------------+---------------+

mysql> select length(null),length(''),length('abc');
+--------------+------------+---------------+
| length(null) | length('') | length('abc') |
+--------------+------------+---------------+
|         NULL |          0 |             3 |
+--------------+------------+---------------+
1 row in set (0.00 sec)

(root@localhost) [jianghu]> select * from Dragon where name is not null;
+-----+--------------+------+--------+--------------+---------+
| Did | Name         | Age  | Gender | MasterId     | ClassId |
+-----+--------------+------+--------+--------------+---------+
|   1 | 风清扬       |   56 | 男     | 独孤求败     |       1 |
|   2 | 萧远山       |   34 | 男     | 2            |       3 |
|   3 | 东方不败     |   25 | 女     | 7            |       2 |
|   4 | 萧峰         |   21 | 男     | 6            |       3 |
|   5 | 张三丰       |  100 | 男     | 2            |       1 |
|   6 | 令狐冲       |   25 | 男     | 3            |       2 |
|   7 | 杨过         |   18 | 男     | 3            |       3 |
|   8 | 小龙女       |   20 | 女     | 3            |       3 |
|   9 | 张无忌       |   27 | 男     | 1            |       8 |
|  10 | 独孤求败     |   66 | 男     | 1            |       1 |
|  11 | 郭靖         |   33 | 男     | 2            |       5 |
|  12 | 黄蓉         |   25 | 女     | 2            |       5 |
|  13 | 胡一刀       |   21 | 男     | 3            |       8 |
|  14 | 袁承志       |   19 | 男     | 5            |       3 |
|  15 | 虚竹         |   19 | 男     | 3            |       1 |
|  16 | 石破天       |   24 | 男     | 1            |       1 |
|  17 | 段誉         |   28 | 男     | 1            |       1 |
|  18 | 阿青         |   28 | 女     | 3            |       5 |
|  20 | xxx          |   50 | 男     | 2            |       1 |
|  21 | xxx          |   50 | 男     | null         |       1 |
|  22 | xxx          |   50 | 男     | NULL         |    NULL |
+-----+--------------+------+--------+--------------+---------+
21 rows in set (0.00 sec)
(root@localhost) [jianghu]> select * from Dragon where classid is  null;
+-----+------+------+--------+----------+---------+
| Did | Name | Age  | Gender | MasterId | ClassId |
+-----+------+------+--------+----------+---------+
|  22 | xxx  |   50 | 男     | NULL     |    NULL |
+-----+------+------+--------+----------+---------+
1 row in set (0.00 sec)

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 次

 存储过程

存储过程优势:

  1. 封装性

    通常完成一个逻辑功能需要多条 SQL 语句,而且各个语句之间很可能传递参数,所以,编写逻辑功能相对来说稍微复杂些,而存储过程可以把这些 SQL 语句包含到一个独立的单元中,使外界看不到复杂的 SQL 语句,只需要简单调用即可达到目的。并且数据库专业人员可以随时对存储过程进行修改,而不会影响到调用它的应用程序源代码

  2. 可增强 SQL 语句的功能和灵活性

    存储过程可以用流程控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

  3. 可减少网络流量

    由于存储过程是在服务器端运行的,且执行速度快,因此当客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而可降低网络负载。

  4. 提高性能

    当存储过程被成功编译后,就存储在数据库服务器里了,以后客户端可以直接调用,这样所有的 SQL 语句将从服务器执行,从而提高性能。但需要说明的是,存储过程不是越多越好,过多的使用存储过程反而影响系统性能

  5. 提高数据库的安全性和数据的完整性

    存储过程提高安全性的一个方案就是把它作为中间组件,存储过程里可以对某些表做相关操作,然后存储过程作为接口提供给外部程序。这样,外部程序无法直接操作数据库表,只能通过存储过程来操作对应的表,因此在一定程度上,安全性是可以得到提高的。

  6. 使数据独立

    数据的独立可以达到解耦的效果,也就是说,程序可以调用存储过程,来替代执行多条的 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 存储过程名

示例(不带参数的创建)
##创建存储过程##
DELIMITER $$                                                      #将语句的结束符号从分号;临时改为两个$$(可以自定义)
CREATE PROCEDURE Proc()                                              #创建存储过程,过程名为Proc,不带参数
-> BEGIN                                                          #过程体以关键字 BEGIN 开始
-> create table mk (id int (10), name char(10),score int (10));   #过程体语句
-> insert into mk values (1, 'wang',13);                          #过程体语句
-> select * from mk;                                              #过程体语句
-> END $$                                                          #过程体以关键字 END 结束

DELIMITER ;                                                          #将语句的结束符号恢复为分号


mysql> delimiter //
mysql> create procedure data()
    -> begin
    -> select now();
    -> end //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call data;
+---------------------+
| now()               |
+---------------------+
| 2021-12-01 17:36:43 |
+---------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)


delimiter @@
create procedure proc (in inname varchar(40))    
begin
select * from info where name=inname;
end @@

delimiter ;        

call proc2('wangwu');    

条件判断
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 [数据库.]存储过程名;        #查看某个存储过程的具体信息
SHOW CREATE PROCEDURE  proc1

##删除存储过程##
存储过程内容的修改方法是通过删除原有存储过程,之后再以相同的名称创建新的存储过程。

DROP PROCEDURE IF EXISTS Proc;

死锁

        是指两个或两个以上的事务在执行过程中,因争夺资源而造成的一种互相等待的现象。就是所谓的锁资源请求产生了回路现象,即死循环,此时称系统处于死锁状态或系统产生了死锁。常见的报错信息为“Deadlock found when trying to get lock...”。      

        在实际应用中,我们要尽量防止死锁等待现象的发生,下面介绍几种避免死锁的方法:

  1. 如果不同程序会并发存取多个表,或者涉及多行记录时,尽量约定以相同的顺序访问表,这样可以大大降低死锁的发生。

  2. 业务中要及时提交或者回滚事务,可减少死锁产生的概率。

  3. 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率。

  4. 对于非常容易产生死锁的业务部分,可以尝试使用升级锁粒度,通过表锁定来减少死锁产生的概率(表级锁不会产生死锁)。

        常见的错误代码

错误代码说 明
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
2008MySQL 客户端内存溢出
2009错误的主机信息
2010通过 UNIX 套接字连接的本地主机
2012服务器握手过程中出错
2013查询过程中丢失了与 SQL 服务器的连接
2014命令不同步,现在不能运行该命令
2024连接到从服务器时出错
2025连接到主服务器时出错
2026SSL 连接错误

这篇关于SQL高级语言(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!