Mysql基础部分总结

时间:2021-03-05 16:58:00 来源:互联网 作者: 神秘的大神 字体:

Mysql基本语法:

文末有mysql资料

执行顺序:

from -> join -> on -> where -> groupby -> avg max .. -> having -> select ->order by

SQL语言分类:

  • DQL:数据查询语言
  • DML:数据操作语言
  • DDL:数据定义语言
  • DCL:数据控制语言

DQL

data query language

SELECT:

  • 可以理解为Java的System.out.println()的输出;
  • 输出内容可以是
    • 字段 select 字段名 from 表名
    • 常量 select 90
    • 函数 select concat('a', 'bbb');
    • 表达式 select 100/1234;
    • 起别名 select last_name as '姓名
    • 去重 select DISTINCT department_id

关于 select中的 '+':

  • select 数值+数值; 直接运算
  • select 字符+数值;先试图将字符转换成数值,如果转换成功,则继续运算;否则转换成0,再做运算
    • select 'aa'+70 #70
    • select 70 +'30' #100
  • select null+值;结果都为null

描述表结构:

DESC departments;

条件查询

/*
 条件运算符: > < <> != >= <=
 逻辑运算符: && || ! and or not 
 模糊查询 : like ,between ,and ,in ,is null 
 		like '%%' 匹配不出null值
 	通配符: 
        % 任意多个字符,包含0个. 
        _ 任意单个字符
        默认转义\
        自定义转义: ESCAPE '转义字符'
 */
 
#1 查询工资在 12000-17000 的员工姓名和工资
SELECT 
last_name as '姓名',salary as '工资'
FROM 
employees
WHERE 
salary BETWEEN 12000 and  17000
;
 #2 查询员工号为 176 的员工的姓名和部门号和年薪
SELECT 
employee_id as '编号',last_name as '姓名',job_id as '部门号',salary*12 as '年薪'
FROM 
employees
WHERE 
employee_id =176 
;
 #3 选择工资不在 5000 到 12000 的员工的姓名和工资
SELECT 
last_name as '姓名',salary as '工资'
FROM 
employees
WHERE 
salary not BETWEEN 5000 and  17000
;
#4 选择在 20 或 50 号部门工作的员工姓名和部门号
SELECT 
last_name as '姓名',department_id as '部门号'
FROM 
employees
WHERE 
-- department_id =20 or department_id =50
department_id in(20,50)
;
#5
#属性判空 选择公司中没有管理者的员工姓名及 job_id
SELECT 
last_name as '姓名',job_id as '工作号'
FROM 
employees
WHERE 
ISNULL(manager_id)
;
#6选择公司中有奖金的员工姓名,工资和奖金级别
SELECT 
last_name as '姓名',commission_pct as '奖金',salary as "工资"
FROM 
employees
WHERE 
not ISNULL(commission_pct)
;
#7 选择员工姓名的第三个字母是 a 的员工姓名
SELECT 
last_name as '姓名'
FROM 
employees
WHERE 
last_name LIKE '__a%'
;

#8 选择姓名中有字母 a 和 e 的员工姓名
SELECT 
last_name as '姓名'
FROM 
employees
WHERE 
last_name LIKE '%a%e%' or last_name LIKE '%e%a%';
;

#9 显示出表 employees 表中 first_name 以 'e'结尾的员工信息
SELECT 
last_name as '姓名'
FROM 
employees
WHERE 
last_name LIKE '%e';
;

#10 显示出表 employees 部门编号在 80-100 之间 的姓名、职位
SELECT 
last_name as '姓名',department_id '部门号'
FROM 
employees
WHERE 
department_id BETWEEN 80 AND 100;
;

#11 显示出表 employees 的 manager_id 是 100,101,110 的员工姓名、职位
SELECT 
last_name as '姓名',job_id as '职位',manager_id
FROM 
employees
WHERE 
manager_id in(100,101,110)
;

排序

#1 查询员工的姓名和部门号和年薪,按年薪降序 按姓名升序
SELECT last_name as name,department_id as dID ,salary*12 as yearsal
FROM employees
ORDER BY yearsal DESC,last_name ASC

#2 选择工资不在 8000 到 17000 的员工的姓名和工资,按工资降序
SELECT last_name as name,salary as sal
FROM employees
WHERE salary not BETWEEN 8000 and 17000
ORDER BY salary DESC

#3 查询邮箱中包含 e 的员工信息,并先按邮箱的字节数降序,再按部门号升序
SELECT department_id as dID,email,LENGTH(email) as '邮箱长度'
FROM employees
ORDER BY LENGTH(email) DESC,department_id ASC

常见函数:

字符函数

  • LOWER(str)
  • UPPER(str)
  • CONCAT(str1,str2,...)
  • SUBSTR(str,pos,len) ps:有多种重载函数
  • LENGTH(str)
  • INSTR(str,substr) 返回子串的第一次出现的索引
  • TRIM([remstr FROM] str) 默认去除前后空格
    • SELECT LENGTH(TRIM('a' FROM "aaa123aaa")) as '长度' => 123
  • REPLACE(str,from_str,to_str)
  • LPAD(str,len,padstr) ,RPAD(str,len,padstr) 用指定字符填充指定长度
    • SELECT LPAD('aaaaa','10','#') => #####aaaaa

数学函数

  • ROUND(X,D) 四舍五入
    • ROUND(45.926,2) => 45.93
  • TRUNCATE 截断
    • TRUNCATE(45.926,2) =>45.92
  • MOD :求余

日期函数

  • now :当前时间

  • STR_TO_DATE(str,format):将日期格式的字符转换成指定格式的日期

    • STR_TO_DATE('2017-01-06 10:20:30','%Y-%m-%d %H:%i:%s')
    • 2017-01-06 10:20:30
  • DATE_FORMAT(date,format) :将日期转换成字符

    • DATE_FORMAT('2021223','%Y年%m月%d日')

流程控制函数

-练习-

#1显示系统时间(注:日期+时间)
SELECT NOW()

#2 计算年薪
SELECT last_name as name,salary,salary*1.2 as newsal
FROM employees



#3将员工的姓名按首字母排序,并写出姓名的长度(length)
SELECT last_name as name ,LENGTH(last_name) as '长度'
FROM employees
ORDER BY SUBSTR(name,1,1) ASC,LENGTH(name) DESC

#4 输出 <last_name> earns <salary> monthly but wants <salary*3>
SELECT CONCAT(last_name,' earn ',ROUND(salary),' monthly but wants ',ROUND(salary*3)) as 'Dream Salary'
FROM employees

#5
/*
job grade
AD_PRES A
ST_MAN B
IT_PROG C
SA_REP D
ST_CLERK E
Last_name  Job_id   Grade
king       AD_PRES  A
*/
SELECT last_name,job_id, #case 也算一个字段,用逗号分隔
CASE job_id
	WHEN 'AD_PRES' THEN
		'A'
	WHEN 'ST_MAN' THEN
	'B'
	WHEN 'IT_PROG' THEN
		'C'
	WHEN 'SA_REP' THEN
	'D'
	WHEN 'ST_CLERK' THEN
	'E'
	ELSE
		'null'
END as 'grade'
FROM employees
ORDER BY grade ASC

分组函数:

特征:

  1. 忽略null值,不计入
  2. 搭配distinct去重
  • AVG() 数值型
  • SUM() 数值型
  • COUNT() 任意数据类型
  • MAX() 任意数据类型
  • MIN() 任意数据类型
COUNT(*):

​ 为什么使用推荐使用COUNT(*)统计总记录数,根据分组函数的特点,null值不计入,当某个字段为null时,可能会出现漏记.

摘自官网:

InnoDB以相同的方式处理SELECT COUNT(*)和SELECT COUNT(1)操作。没有性能差异。

分组查询:

1.单子段分组:

select 分组函数,分组后的字段
from 表
【where 筛选条件】             -- 分组前的筛选条件
group by 分组的字段
【having 分组后的筛选】 -- 分组函数,筛选满足条件的组
【order by 排序列表】

2.按函数分组

group by 后还可使用函数,

​ 例子:按员工姓名长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些;

SELECT LENGTH(last_name) as 'length', COUNT(*)
FROM employees
GROUP BY LENGTH(last_name)
HAVING COUNT(*) >3

3.多字段分组

例子:查询每个部门每个工种的员工平均工资

SELECT AVG(salary),department_id,job_id
FROM employees
WHERE not ISNULL(department_id)
GROUP BY department_id,job_id
ORDER BY AVG(salary) ASC

φ(゜▽゜*)♪

-练习一-

#1.查询各 job_id 的员工工资的最大值,最小值,平均值,总和,并按 job_id 升序
SELECT job_id, MAX(salary),MIN(salary),AVG(salary),SUM(salary)
FROM employees
GROUP BY job_id
ORDER BY job_id ASC
#2.查询各个管理者手下员工的最低工资,其中最低工资不能低于 6000, 没有管理者的员工不计算在内
SELECT manager_id, MIN(salary)
FROM employees
WHERE not ISNULL(manager_id) -- 分组前的筛选条件
GROUP BY manager_id
HAVING MIN(salary)>=6000 -- 筛选满足条件的组
ORDER BY manager_id ASC 
#3.查询员工表中的最大入职时间和最小入职时间的相差天数
SELECT DATEDIFF(MAX(hiredate),MIN(hiredate))
FROM employees

联合查询:

UNION

when use:查新的结果来自多个表,且多个表没有直接的连接关系,但查询的信息一致

特点:

  1. 查询的列数是一致的,顺序也最好一致
  2. union默认去重,如果使用 union all 可包含重复项

连接查询:

笛卡尔乘积现象:

SELECT b.*,g.*
FROM boys b,beauty g

表1 有m行,表2 有n行,结果=m*n;

原因:无有效的连接条件

避免:可以使用WHERE 添加有效的连接条件

内连接:

返回两张表都满足条件的部分.

  • 等值连接 :连接条件中使用等于号(=)运算符比较
  • 非等值连接:连接条件中不使用等于号(=)运算符比较
  • 自连接 :相当于一张表当作俩张表使用.
#(等值连接)
    #查询每个城市的部门个数
    SELECT city,COUNT(*)
    FROM locations l,departments d
    WHERE l.location_id = d.location_id
    GROUP BY city
    # 查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
    SELECT	d.department_name,d.manager_id ,MIN(e.salary) 
    FROM employees e,departments d
    WHERE e.department_id =d.department_id AND  NOT ISNULL(e.commission_pct)
    GROUP BY e.department_id
    #查询每个国家下的部门个数大于 2 的国家编号
    SELECT l.country_id
    FROM locations l,departments d
    WHERE l.location_id = d.location_id
    GROUP BY country_id
    HAVING COUNT(*)>2

#不等值连接
    #依据job_grades给每个员工工资分等级
    SELECT e.salary ,jg.grade_level
    FROM employees e,job_grades jg
    WHERE e.salary BETWEEN jg.lowest_sal AND jg.highest_sal
    ORDER BY e.salary ASC

	
#自连接 
    #选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式
    # employees Emp manager Mgr
    SELECT e.last_name as 'employees' ,e.employee_id as 'Emp' ,m.last_name as' manager',m.employee_id as'Mgr'
    FROM employees e,employees m
    WHERE e.manager_id =m.employee_id

外连接:

外链接的查询结果=主表中的所有记录+从表匹配值(ifnull 则显示null)

  • 左外连接 left join 左边的是主表

  • 右外连接 right join 右边的是主表

  • 全外连接: FULL JOIN (Mysql不支持)

    •   select <select_list>
        from A full join B
        on A.key=B.key
        where A.key is null or b.key is null
      
sql99语法
select  -- 查询列表
from 表1 -- [连接类型]
join 表2
on 连接条件 --
where 筛选条件
#查询beauty中男朋友情况
SELECT g.`name` ,b.id,b.boyName
FROM beauty g LEFT JOIN boys b
on g.boyfriend_id =b.id
#查询哪一个部门没有员工
SELECT d.* ,e.employee_id,e.manager_id
FROM departments d LEFT JOIN employees e
on d.department_id = e.department_id
WHERE e.manager_id is null
#查询部门名为 SAL,IT的员工信息
SELECT e.*,d.department_name
FROM departments d RIGHT JOIN employees e
on d.department_id = e.department_id
WHERE d.department_name in('SAL','IT')

交叉连接:

即笛卡尔乘积结果


子查询:

分类:

  1. 标量子查询 - 结果集只有一行一列
  2. 列子查询 -一列多行 (单一字段)
  3. 行子查询 -一行多列(可以多行多列,多字段)
  4. 表子查询 -多行多列

位置:

  1. select +标量子查询
  2. from +表子查询
  3. where /having +(标量+列查询+行)
  4. exists

where /having :

  • 标量子查询
  • 列子查询
  • 行子查询

特点:

  • 标量查询 搭配 单行操作符 > < <> >= <=
  • 列子查询 搭配 多行操作符 in ,any ,some ,all
标量子查询:
#返回job_id与141号员工相同,salary比143号员工多的 员工姓名,job_id,和工资
SELECT last_name,job_id,salary
FROM employees
WHERE job_id=(
	SELECT job_id
	FROM employees
	WHERE employee_id=141
) AND salary >(
	SELECT salary
	FROM employees
	WHERE employee_id=143
)
#返回公司工资最少的员工信息,last_name,job_id,salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary =(
	SELECT MIN(salary)
	FROM employees
)
列子查询(多行):

any:和子查询返回的某一个比较

In/not in : 等于列表中的任意一个

#返回location_id是1400或1700的部门中所有员工姓名
SELECT last_name
FROM employees
WHERE department_id in (
	SELECT department_id
	FROM departments
	WHERE location_id in (1400,1700)
)
#返回其他工种比job_id为'IT_PROG'工种任一工资低的员工的员工号,姓名,job_id,以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary < ANY(
	SELECT salary
	FROM employees
	WHERE job_id = 'IT_PROG'
) AND job_id <>'IT_PROG';
行子查询:
#返回员工编号最小,工资最高的信息.
SELECT * 
FROM employees
WHERE (employee_id,salary)=(
	SELECT MIN(employee_id),MAX(salary)
	FROM employees
)

select:

标量子查询
#查询每个部门的员工个数,显示departments表
SELECT d.* ,(
	SELECT COUNT(*)
	FROM employees e
	WHERE d.department_id=e.department_id
) 统计
FROM departments d   -- 27
/*
错误代码 why?
SELECT d.* ,(
	SELECT COUNT(*)
	FROM employees e
	WHERE d.department_id=e.department_id
) 'ANS'
FROM employees e,departments d
2889
*/

from:

#查询每个部门的平均工资的工资等级
SELECT ag_dep.*,g.grade_level
FROM (
	SELECT AVG(salary) as ag,department_id
	FROM employees
	GROUP BY department_id
)ag_dep
INNER JOIN job_grades g -- 直接起别名 如果 AS 'g'则会报错
ON ag_dep.ag BETWEEN g.lowest_sal AND g.highest_sal

exists(相关子查询):

/*
语法:
EXISTS(完整的查询语句)
返回:
0或1
*/
#查询没有女朋友的boy
SELECT bo.* 
FROM boys bo
WHERE NOT EXISTS (
	SELECT boyfriend_id
	FROM beauty g
	WHERE bo.id =g.boyfriend_id
)
#连接查询
SELECT b.*
FROM boys b LEFT JOIN beauty g
on b.id= g.boyfriend_id
WHERE g.name is NULL

-练习-

-- 1. 查询和 Zlotkey 相同部门的员工姓名和工资
SELECT last_name,salary,department_id
FROM employees
WHERE department_id=(
		SELECT department_id
		FROM employees
		WHERE last_name ='Zlotkey'
)#34
-- 2. 查询工资比公司平均工资高的员工的员工号,姓名和工资
SELECT employee_id,last_name,salary
FROM employees
WHERE salary>(
	SELECT AVG(salary)
	FROM employees
)#51
-- 3. 查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资

SELECT employee_id,last_name,salary
FROM (
	SELECT AVG(e.salary) ag_sal,e.department_id eid
	FROM employees e
	GROUP BY department_id
) tab1 INNER JOIN employees e1
on e1.department_id = tab1.eid
WHERE e1.salary >tab1.ag_sal
ORDER BY e1.employee_id #38

-- 4. 查询和姓名中包含字母 u 的员工在相同部门的员工的员工号和姓名
SELECT employee_id,last_name
FROM employees
WHERE department_id in(
	SELECT DISTINCT department_id
	FROM employees 
	WHERE last_name LIKE '%u%'
)#96

-- 5. 查询在部门的 location_id 为 1700 的部门工作的员工的员工号
SELECT employee_id
FROM employees
WHERE department_id in(
	SELECT department_id
	FROM departments
	WHERE location_id=1700
)#18


-- 6. 查询管理者是 King 的员工姓名和工资

SELECT last_name,salary
FROM employees e
WHERE manager_id in(
	SELECT employee_id
	FROM employees
	WHERE last_name ='K_ing'
)#14

-- 7. 查询工资最高的员工的姓名,要求 first_name 和 last_name 显示为一列,列名为 姓.名
SELECT CONCAT(first_name,last_name) as "姓名"
FROM employees
WHERE salary =(
	SELECT MAX(salary)
	FROM employees
)

分页查询:

select  -- 查询列表
from 表1 
[type] join 表2-- [连接类型] 
on 连接条件 --
where 筛选条件
group by 分组字段
having 分组后筛选
order by 排序字段
limit offset ,size;
offset = (page-1)*size

DML:

data manipulation language

插入:

insert into 表名(列名,...) values(值1) -- 一
insert into 表名 set 字段=值,字段=值,... -- 二
#1 插入值类型与列类型一致 ,可调换顺序 ,不可为null的值必须插入值
#2 方式一支持 一次插入多行 + 子查询

修改:

update 表名 set 字段=值,字段=值 【where 筛选条件】; -- 1
-- 2 多表更新
update 表1 别名 
left|right|inner join 表2 别名 
on 连接条件  
set 字段=值,字段=值 
【where 筛选条件】;

删除:

delete from 表名 【where 筛选条件】【limit 条目数】

truncate table 表名

#多表删除 实例
delete g
from beauty g
inner join boys b 
on g.boyfriends_id = b.id
where b.boyName='xxx';

delete 与 truncate 区别:

  1. truncate删除后,如果再插入,标识列从1开始
    delete删除后,如果再插入,标识列从断点开始
  2. delete可以添加筛选条件
    truncate不可以添加筛选条件
  3. truncate效率较高
  4. truncate没有返回值
    delete可以返回受影响的行数
  5. truncate不可以回滚
    delete可以回滚

DDL:

data defination language

库:

#创建
CREATE DATABASE if NOT EXISTS boos;
#重命名
RENAME DATABASE boos TO books;
#设置字符集
ALTER DATABASE boos CHARACTER SET gbk;
#删除库
DROP DATABASE boos;

表:

drop table if 表名 exists
create table 【if not exists】 表名(
	字段名 字段类型(长度) 【约束】,
	字段名 字段类型 【约束】,
	....
	字段名 字段类型 【约束】 
)

create table if not exists books(
	id INT(2) AUTO_INCREMENT,
	bname VARCHAR(20),
  	privce DOUBLE ,
	PRIMARY KEY (id)
)

1.添加列
alter table 表名 add column 列名 类型 【first|after 字段名】;

ALTER TABLE books ADD COLUMN author INT;

2.修改列的类型或约束
alter table 表名 modify column 列名 新类型 【新约束】;

alter table books modify column name DOUBLE UNIQUE;

3.修改列名
alter table 表名 change column 旧列名 新列名 类型;

同时可修改类型

alter table books change bname name varchar(30);

4 .删除列
alter table 表名 drop column 列名;

ALTER TABLE books DROP COLUMN NAME

5.修改表名
alter table 表名 rename 【to】 新表名;

alter table books rename to new_books;

6.表的复制

#1、复制表的结构
create table 表名 like 旧表;
CREATE TABLE copyed LIKE new_books

#2、复制表的结构+数据
create table 表名 
select 查询列表 from 旧表【where 筛选】;

CREATE TABLE copy_books
SELECT * FROM new_books WHERE 1=1;

数据类型:

整型:tinyint、smallint、mediumint、int/integer、bigint

  • ①都可以设置无符号和有符号,默认有符号,通过unsigned设置无符号(没有符数)
  • 长度
    • 存放数据大小依据数据类型已经确定. 而长度代表显示的最大宽度,而不够则用左边0填充,但需搭配zerofill,并且默认为无符号整型

浮点型:

  • 定点数:decimal(M,D)
  • 浮点数: float(M,D) , double(M,D)

M = 整数位数+小数位数

D =小数位数

Mysql8中: 如果D=3,插入12.456则会四舍五入为12.5

字符型:char、varchar、binary、varbinary、enum、set、text、blob

char:char(M),最大长度不能超过M,其中M可以省略,默认为1

varchar:可变长度的字符,写法为varchar(M),最大长度不能超过M,其中M不可以省略

日期型:year,date日期 ,time时间, datetime 日期时间

6ZNBuT.png

约束:

  • NOT NULL:非空,该字段的值必填
  • UNIQUE:唯一,该字段的值不可重复
  • DEFAULT:默认,该字段的值不用手动插入有默认值
  • CHECK:检查,mysql不支持
  • PRIMARY KEY:主键,该字段的值不可重复并且非空 unique+not null
  • FOREIGN KEY:外键,用于限制两个表的关系,在从表添加外键约束,用于引用主表某列的值

主键,外键:

主键:一个表至多有一个主键,但可以有多个唯一

外键:

  1. 在从表设置外键关系
  2. 从表外键列类型 和 主表的关联列类型要求一致或兼容
  3. 主表的关联列必须是一个key(主键,唯一)
  4. 插入数据 ,先插入主表,再删除从表
    • 删除数据时,先删除从表,再删除主表
支持类型 是否可起约束名
列级约束 外键约束没有效果 不可以
表级约束 除了非空和默认 可以,但对主键无效
create table 表名(
    #列级约束
	字段名 字段类型 not null,#非空
	字段名 字段类型 primary key,#主键
	字段名 字段类型 unique,#唯一
	字段名 字段类型 default 值,#默认
    #表级约束
	constraint 约束名 foreign key(字段名) references 主表(被引用列),
    constraint fk_stu_major foreign key(majorid) references major(id),
    
    constraint 约束名 [约束](字段), -- 约束名 = 别名 ,变量
    constraint pk  primary key(id)
)
show INDEX FROM 表名

标识列:

自增长列:

  • 一个表至多有一个自增长列
  • 自增长列只能支持数值型
  • 自增长列必须为一个key

TCL

Transaction Control Language 事务控制语言

事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行

事务特点:

  • A: Atomicity 一个事务是不可再分割的整体,要么都执行要么都不执行
  • C: Consistency 一个事务可以使数据从一个一致状态切换到另外一个一致的状态
  • I:Isolation 一个事务不受其他事务的干扰,多个事务互相隔离的
  • D:Durability 一个事务一旦提交了,则永久的持久化到本地
set autocommit=0
start transaction 
delete from account where id =25
savepoint a #设置保存点
delete from account where id =28
rollback to a; #回滚到a

重点在spring中介绍事务操作

其他

视图:

what:虚拟表,通过表动态生成的数据 ,只保存sql逻辑不保存结果

where:

  • 多个地方用到同样的查询结果
  • 使用的sql语句比较复杂
#创建
create VIEW myview1 
As
SELECT last_name,department_name,job_title
FROM employees e
join departments d on e.department_id = d.department_id
join jobs j on j.job_id = e.job_id


SELECT * from myview1 where last_name like '%a%'

#修改
create or replace view [视图名]
as
[查询语句]


#删除 drop view [视图名]

变量:

系统变量:

  • 全局变量:服务器层面上的,必须拥有super权限才能为系统变量赋值,作用域为整个服务器,也就是针对于所有连接(会话)有效

  • 会话变量:服务器为每一个连接的客户端都提供了系统变量,作用域为当前的连接(会话)

  •   show 【global|session 】variables like '';
      set 【global|session 】 变量名=值
    

自定义变量:

  • 用户变量:针对于当前连接(会话)生效

    •   set @变量名=值;
        select @变量名;
        set @m =1;
        set @n = 2;
        set @sum = @m +@n;
        select @sum;
      
  • 局部变量:仅仅在定义它的begin end中有效

    •   declare 变量名 类型 【default 值】;
      

存储过程:

what :一组预先编译号的SQL语句集合

why use:

  • 提高代码的重用性
  • 简化操作
  • 减少编译次数和数据库服务器连接次数
create procedure 存储过程名(参数列表)
begin
[sql 语句]
end
参数列表:
参数模式 参数名  参数类型
In    stuname  varchar(20)
参数模式:
  • in:该参数可作为输入
  • out:该参数可以作为返回值
  • inout:输入+返回值

调用: call 存储过程名(实参列表)

delimiter 结束标记:

delimiter $ -- 任意

案例:

IN:

CREATE DEFINER=`root`@`localhost` PROCEDURE `logincheck`(IN username VARCHAR(20),IN password VARCHAR(20))
BEGIN
	#Routine body goes here...
	DECLARE result VARCHAR(20) DEFAULT '';
	SELECT COUNT(*) INTO result
	FROM admin
	WHERE admin.username =username AND
	admin.`password` =password;
	SELECT IF (result>0 ,'成功','失败');
END

CALL logincheck('admin1','123')
#JDBC中
db.connect( "db_host" ).execute_sql( "CALL logincheck('admin1','123')" );

OUT:

CREATE DEFINER=`root`@`localhost` PROCEDURE `findboy`(In butyName VARCHAR(20),OUT boyName VARCHAR(20))
BEGIN
	#Routine body goes here...
	SELECT bo.boyName INTO boyName
	FROM boys bo
	JOIN beauty g on bo.id = g.boyfriend_id
	WHERE g.name = butyName;
END

CALL findboy('小昭',@boyName);
SELECT @boyName

函数:

区别:

  • 存储过程:可以有0个返回,也可以有多个返回 ,批量操作
  • 函数: 有且仅有一个1个 , 适合处理数据返回结果
CREATE FUNCTION `函数名`(参数列表)
	RETURNS 返回类型
BEGIN
	#Routine body goes here...
	
	RETURN 0;
END;
--------------------
CREATE DEFINER = CURRENT_USER FUNCTION ``()
	RETURNS integer
BEGIN
	#Routine body goes here...
	
	RETURN 0;
END;

select 函数名(参数列表)

DCL:

data control language

流程控制结构:

分支:

CREATE PROCEDURE casse(IN score INT)
BEGIN
	CASE 
	WHEN scorce>=90 THEN
		SELECT 'A';
	WHEN scorce>=90 THEN
		SELECT 'B';
	ELSE
		SELECT 'C';	
END CASE;
END;
#---------------------------------

CREATE PROCEDURE casse(IN score INT)
BEGIN
 IF search_condition THEN
	statement_list
	ELSEIF search_condition THEN
	statement_list
ELSE
	statement_list
END IF;
END;

#-------------循环-------------------
CREATE PROCEDURE casse(IN cnt INT)
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i<=cnt DO
	INSERT into admin(username,`password`) VALUES(xxx,xxx)
END WHILE;

END;

链接:https://pan.baidu.com/s/1EeBnOhgMSJjvn35RZtz5sw
提取码:3mji
复制这段内容后打开百度网盘手机App,操作更方便哦