数据操作语言
插入: insert
修改: update
删除: delete
语法:
insert into 表名(列名,...) values(值1,...);
SELECT * FROM beauty;
INSERT INTO beauty(id,NAME,sex,borndate,phone,photo,boyfriend_id)
VALUES(13,'唐艺昕','女','1990-4-23','1898888888',NULL,2);
方式一
INSERT INTO beauty(id,NAME,sex,borndate,phone,photo,boyfriend_id)
VALUES(13,'唐艺昕','女','1990-4-23','1898888888',NULL,2);
方式二
INSERT INTO beauty(id,NAME,sex,phone)
VALUES(15,'娜扎','女','1388888888');
列的顺序是否可以调换
INSERT INTO beauty(NAME,sex,id,phone)
VALUES(‘蒋欣’,‘女’,16,‘110’);
列数和值的个数必须一致
INSERT INTO beauty(NAME,sex,id,phone)
VALUES('关晓彤','女',17,'110');
INSERT INTO beauty
VALUES(18,'张飞','男',NULL,'119',NULL,NULL);
语法:insert into 表名 set 列名=值,列名=值,...
INSERT INTO beauty
SET id=19,NAME='刘涛',phone='999';
INSERT INTO beauty
VALUES(23,'唐艺昕1','女','1990-4-23','1898888888',NULL,2)
,(24,'唐艺昕2','女','1990-4-23','1898888888',NULL,2)
,(25,'唐艺昕3','女','1990-4-23','1898888888',NULL,2);
INSERT INTO beauty(id,NAME,phone)
SELECT 26,'宋茜','11809866';
INSERT INTO beauty(id,NAME,phone)
SELECT id,boyname,'1234567'
FROM boys WHERE id<3;
语法:
update 表名 set 列=新值,列=新值,... where 筛选条件;
语法:
sql92语法:
update 表1 别名,表2 别名 set 列=值,... where 连接条件 and 筛选条件;
sql99语法:
update 表1 别名 inner|left|right join 表2 别名 on 连接条件 set 列=值,... where 筛选条件;
案例1: 修改beauty表中姓唐的女神的电话为13899888899
UPDATE beauty SET phone = '13899888899'
WHERE NAME LIKE '唐%';
案例2: 修改boys表中id好为2的名称为张飞, 魅力值 10
UPDATE boys SET boyname='张飞',usercp=10
WHERE id=2;
案例1:修改张无忌的女朋友的手机号为114
UPDATE boys bo
INNER JOIN beauty b ON bo.`id`=b.`boyfriend_id`
SET b.`phone`='119',bo.`userCP`=1000
WHERE bo.`boyName`='张无忌';
案例2: 修改没有男朋友的女神的男朋友编号都为2号
UPDATE boys bo
RIGHT JOIN beauty b ON bo.`id`=b.`boyfriend_id`
SET b.`boyfriend_id`=2
WHERE bo.`id` IS NULL;
SELECT * FROM boys;
delete
语法:
单表的删除
delete from 表名 where 筛选条件
多表的删除[补充]
sql92语法
delete 表1的别名,表2的别名
from 表1 别名,表2 别名
where 连接条件
and 筛选条件;
sql99
delete 表1的别名,表2的别名
from 表1 别名
inner|left|right join 表2 别名 on 连接条件
where 筛选条件;
truncate
语法:truncate table 表名;
delete
案例: 删除手机号以9结尾的女神信息
DELETE FROM beauty WHERE phone LIKE '%9';
SELECT * FROM beauty;
案例: 删除张无忌的女朋友的信息
DELETE b
FROM beauty b
INNER JOIN boys bo ON b.`boyfriend_id` = bo.`id`
WHERE bo.`boyName`='张无忌';
案例: 删除黄晓明的信息以及他女朋友的信息
DELETE b,bo
FROM beauty b
INNER JOIN boys bo ON b.`boyfriend_id`=bo.`id`
WHERE bo.`boyName`='黄晓明';
案例: 将魅力值>100的男神信息删除
TRUNCATE TABLE boys ;
delete pk truncate面试题
情况 | delete |
truncate |
---|---|---|
where 筛选 |
可以加 | 不能加 |
效率 | 低 | 高 |
删除的表有自增长列再插入时 | 值从断点开始 | 值从1开始 |
返回值 | 有 | 无 |
回滚 | 可以 | 不能 |
注解: truncate
比 delete
速度快, 且使用的系统和事务日志资源少. delete
语句每次删除一行, 并在事务日志中为所删除的每行记录一项. 所以可以对delete操作进行roll back, 而truncate
是ddl语言, 隐式提交, 因此不可以使用rollback.
SELECT * FROM boys;
DELETE FROM boys;
TRUNCATE TABLE boys;
INSERT INTO boys (boyname,usercp)
VALUES('张飞',100),('刘备',100),('关云长',100);
数据定义语言, 库和表的管理
库的管理: 创建、修改、删除
表的管理: 创建、修改、删除
创建: create
修改: alter
删除: drop
语法:
create database [if not exists]库名;
案例: 创建库Books
CREATE DATABASE IF NOT EXISTS books ;
改名:
RENAME DATABASE books TO 新库名;
更改库的字符集:
ALTER DATABASE books CHARACTER SET gbk;
DROP DATABASE IF EXISTS books;
语法:
create table 表名(
列名 列的类型[(长度) 约束],
列名 列的类型[(长度) 约束],
列名 列的类型[(长度) 约束],
...
列名 列的类型[(长度) 约束]
)
案例: 创建表Book
CREATE TABLE book(
id INT,#编号
bName VARCHAR(20),#图书名
price DOUBLE,#价格
authorId INT,#作者编号
publishDate DATETIME#出版日期
);
DESC book;
案例: 创建表author
CREATE TABLE IF NOT EXISTS author(
id INT,
au_name VARCHAR(20),
nation VARCHAR(10)
)
DESC author;
语法
alter table 表名 add|drop|modify|change column 列名 [列类型 约束];
**案例: book表中的publishdate字段改名
ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;
ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;
ALTER TABLE author ADD COLUMN annual DOUBLE;
ALTER TABLE book_author DROP COLUMN annual;
ALTER TABLE author RENAME TO book_author;
DESC book;
DROP TABLE IF EXISTS book_author;
SHOW TABLES;
通用的写法
DROP DATABASE IF EXISTS 旧库名;
CREATE DATABASE 新库名;
DROP TABLE IF EXISTS 旧表名;
CREATE TABLE 表名();
INSERT INTO author VALUES
(1,'村上春树','日本'),
(2,'莫言','中国'),
(3,'冯唐','中国'),
(4,'金庸','中国');
SELECT * FROM Author;
SELECT * FROM copy2;
CREATE TABLE copy LIKE author;
CREATE TABLE copy2
SELECT * FROM author;
CREATE TABLE copy3
SELECT id,au_name
FROM author
WHERE nation='中国';
CREATE TABLE copy4
SELECT id,au_name
FROM author
WHERE 0;
一种限制, 用于限制表中的数据, 为了保证表中的数据的准确和可靠性
NOT NULL
: 非空, 用于保证该字段的值不能为空
比如姓名, 学号等
DEFAULT
: 默认, 用于保证该字段有默认值
比如性别
PRIMARY KEY
:主键, 用于保证该字段的值具有唯一性, 并且非空
比如学号、员工编号等
UNIQUE
:唯一, 用于保证该字段的值具有唯一性, 可以为空
比如座位号
CHECK
:检查约束mysql中不支持
比如年龄、性别
FOREIGN KEY
:外键, 用于限制两个表的关系, 用于保证该字段的值必须来自于主表的关联列的值, 在从表添加外键约束, 用于引用主表中某列的值. 比如学生表的专业编号, 员工表的部门编号, 员工表的工种编号.
添加约束的时机
1.创建表时
2.修改表时
约束的添加分类
列级约束:六大约束语法上都支持: 但外键约束没有效果;
表级约束: 除了非空、默认,其他的都支持
主键和唯一的大对比
类型 | 保证唯一性 | 是否允许为空 | 一个表中可以有多少个 | 是否允许组合 |
---|---|---|---|---|
主键 | √ | × | 至多有1个 | √, 但不推荐 |
唯一 | √ | √ | 可以有多个 | √,但不推荐 |
外键
CREATE TABLE 表名(
字段名 字段类型 列级约束,
字段名 字段类型,
表级约束);
语法:
直接在字段名和类型后面追加约束类型即可.
只支持: 默认, 非空, 主键,唯一
CREATE DATABASE students;
USE students;
DROP TABLE stuinfo;
CREATE TABLE stuinfo(
id INT PRIMARY KEY,#主键
stuName VARCHAR(20) NOT NULL UNIQUE,#非空
gender CHAR(1) CHECK(gender='男' OR gender ='女'),#检查
seat INT UNIQUE,#唯一
age INT DEFAULT 18,#默认约束
majorId INT REFERENCES major(id)#外键
);
CREATE TABLE major(
id INT PRIMARY KEY,
majorName VARCHAR(20)
);
#查看stuinfo中的所有索引,包括主键、外键、唯一
SHOW INDEX FROM stuinfo;
语法: 在各个字段的最下面 [constraint 约束名] 约束类型(字段名)
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
id INT,
stuname VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT,
CONSTRAINT pk PRIMARY KEY(id),#主键
CONSTRAINT uq UNIQUE(seat),#唯一键
CONSTRAINT ck CHECK(gender ='男' OR gender = '女'),#检查
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外键
);
SHOW INDEX FROM stuinfo;
CREATE TABLE IF NOT EXISTS stuinfo(
id INT PRIMARY KEY,
stuname VARCHAR(20),
sex CHAR(1),
age INT DEFAULT 18,
seat INT UNIQUE,
majorid INT,
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)
);
理解约束是modify
, 表级约束是add
添加列级约束
alter table 表名 modify column 字段名 字段类型 新约束;
添加表级约束
alter table 表名 add [constraint 约束名] 约束类型(字段名) [外键的引用];
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
id INT,
stuname VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT
)
DESC stuinfo;
#1.添加非空约束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NOT NULL;
#2.添加默认约束
ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;
#3.添加主键
#①列级约束
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
#②表级约束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);
#4.添加唯一
#①列级约束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
#②表级约束
ALTER TABLE stuinfo ADD UNIQUE(seat);
#5.添加外键
ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id);
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;
alter table modify column stu_name varchar(20);
ALTER TABLE stuinfo MODIFY COLUMN age INT ;
ALTER TABLE stuinfo DROP PRIMARY KEY;
ALTER TABLE stuinfo DROP INDEX seat;
ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;
SHOW INDEX FROM stuinfo;
又称为自增长列
含义: 可以不用手动的插入值, 系统提供默认的序列值
特点:
DROP TABLE IF EXISTS tab_identity;
CREATE TABLE tab_identity(
id INT ,
NAME FLOAT UNIQUE AUTO_INCREMENT,
seat INT
);
TRUNCATE TABLE tab_identity;
INSERT INTO tab_identity(id,NAME) VALUES(NULL,'john');
INSERT INTO tab_identity(NAME) VALUES('lucy');
SELECT * FROM tab_identity;
SHOW VARIABLES LIKE '%auto_increment%';
SET auto_increment_increment=3;
数值型
整型
小数:
定点数
浮点数
字符型:
较短的文本:char、varchar
较长的文本:text、blob(较长的二进制数据)
日期型
tinyint | smallint | mediumint | int/integer | bigint |
---|---|---|---|---|
1 | 2 | 3 | 4 | 8 |
特点:
① 如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加unsigned关键字
② 如果插入的数值超出了整型的范围,会报out of range异常,并且插入临界值
③ 如果不设置长度,会有默认的长度
长度代表了显示的最大宽度,如果不够会用0在左边填充,但必须搭配zerofill使用!
DROP TABLE IF EXISTS tab_int;
CREATE TABLE tab_int(
t1 INT(7) ZEROFILL,
t2 INT(7) ZEROFILL
);
DESC tab_int;
INSERT INTO tab_int VALUES(-123456);
INSERT INTO tab_int VALUES(-123456,-123456);
INSERT INTO tab_int VALUES(2147483648,4294967296);
INSERT INTO tab_int VALUES(123,123);
SELECT * FROM tab_int;
①
M:整数部位+小数部位
D:小数部位
如果超过范围,则插入临界值
②
M和D都可以省略
如果是decimal,则M默认为10,D默认为0
如果是float和double,则会根据插入的数值的精度来决定精度
③定点型的精确度较高,如果要求插入数值的精度较高如货币运算等则考虑使用
#测试M和D
DROP TABLE tab_float;
CREATE TABLE tab_float(
f1 FLOAT,
f2 DOUBLE,
f3 DECIMAL
);
SELECT * FROM tab_float;
DESC tab_float;
INSERT INTO tab_float VALUES(123.4523,123.4523,123.4523);
INSERT INTO tab_float VALUES(123.456,123.456,123.456);
INSERT INTO tab_float VALUES(123.4,123.4,123.4);
INSERT INTO tab_float VALUES(1523.4,1523.4,1523.4);
原则: 所选择的类型越简单越好, 能保存数值的类型越小越好
char
, varchar
binary
和varbinary
用于保存较短的二进制enum
用于保存枚举set
用于保存集合text
blob
(较大的二进制)特点:
写法 | M的意思 | 特点 | 空间的耗费 | 效率 |
---|---|---|---|---|
char char(M) |
最大的字符数, 可以省略, 默认为1 | 固定长度的字符 | 比较耗费 | 高 |
varchar varchar(M) |
最大的字符数, 不可以省略 | 可变长度的字符 | 比较节省 | 低 |
CREATE TABLE tab_char(
c1 ENUM('a','b','c')
);
INSERT INTO tab_char VALUES('a');
INSERT INTO tab_char VALUES('b');
INSERT INTO tab_char VALUES('c');
INSERT INTO tab_char VALUES('m');
INSERT INTO tab_char VALUES('A');
SELECT * FROM tab_set;
CREATE TABLE tab_set(
s1 SET('a','b','c','d')
);
INSERT INTO tab_set VALUES('a');
INSERT INTO tab_set VALUES('A,B');
INSERT INTO tab_set VALUES('a,c,d');
特点:
写法 | 字节 | 范围 | 时区等的影响 |
---|---|---|---|
datetime |
8 | 1000-9999 | 不受 |
timestamp |
4 | 1970-2038 | 受 |
CREATE TABLE tab_date(
t1 DATETIME,
t2 TIMESTAMP
);
INSERT INTO tab_date VALUES(NOW(),NOW());
SELECT * FROM tab_date;
SHOW VARIABLES LIKE 'time_zone';
SET time_zone='+9:00';
系统变量
全局变量
会话变量
自定义变量
用户变量
局部变量
说明: 变量由系统定义, 不是用户定义, 属于服务器层面
注意: 全局变量需要添加global
关键字, 会话变量需要添加session
关键字, 如果不写, 默认会话级别
使用步骤:
1、查看所有系统变量
show global|[session]variables;
2、查看满足条件的部分系统变量
show global|[session] variables like '%char%';
3、查看指定的系统变量的值
select @@global|[session]系统变量名;
4、为某个系统变量赋值
方式一:
set global|[session]系统变量名=值;
方式二:
set @@global|[session]系统变量名=值;
作用域
针对于所有会话(连接)有效, 但不能跨重启
语法如下:
#①查看所有全局变量
SHOW GLOBAL VARIABLES;
#②查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';
#③查看指定的系统变量的值
SELECT @@global.autocommit;
#④为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;
作用域
针对于当前会话(连接)有效
#①查看所有会话变量
SHOW SESSION VARIABLES;
#②查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%char%';
#③查看指定的会话变量的值
SELECT @@autocommit;
SELECT @@session.tx_isolation;
#④为某个会话变量赋值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';
说明: 变量由用户自定义, 而不是系统提供的
使用步骤:
作用域
针对于当前会话(连接)有效, 作用域同于会话变量
赋值操作符为=
或:=
#①声明并初始化
SET @变量名=值;
SET @变量名:=值;
SELECT @变量名:=值;
#②赋值(更新变量的值)
#方式一:
SET @变量名=值;
SET @变量名:=值;
SELECT @变量名:=值;
#方式二:
SELECT 字段 INTO @变量名
FROM 表;
#③使用(查看变量的值)
SELECT @变量名;
作用域
仅仅在定义它的begin end
块中有效
应用在 begin end
中的第一句话
#1. 声明
DECLARE 变量名 类型;
DECLARE 变量名 类型 [DEFAULT 值];
#2. 赋值(更新变量的值)
#方式一:
SET 局部变量名=值;
SET 局部变量名:=值;
SELECT 局部变量名:=值;
#方式二:
SELECT 字段 INTO 具备变量名
FROM 表;
#3. 使用(查看变量的值)
SELECT 局部变量名;
#用户变量
SET @m=1;
SET @n=1;
SET @sum=@m+@n;
SELECT @sum;
#局部变量
DECLARE m INT DEFAULT 1;
DECLARE n INT DEFAULT 1;
DECLARE SUM INT;
SET SUM=m+n;
SELECT SUM;
类型 | 作用域 | 定义位置 | 语法 |
---|---|---|---|
用户变量 | 当前会话 | 会话的任何地方 | 加@符号, 不用指定类型 |
局部变量 | 定义它的BEGIN END 中 |
BEGIN END 的第一句话 |
一般不用加@,需要指定类型 |
存储过程和函数: 类似于java中的方法
好处: 提高代码的重用性; 简化操作.
含义: 一组预先编译好的SQL语句的集合, 理解成批处理语句
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的SQL语句)
END
注意:
参数列表包含三部分: 参数模式, 参数名, 参数类型
举例: in stuname varchar(20)
in
: 该参数可以作为输入, 也就是该参数需要调用方传入值
out
: 该参数可以作为输出, 也就是该参数可以作为返回值
inout
: 该参数既可以作为输入又可以作为输出, 也就是该参数既需要传入值, 又可以返回值
begin end
省略如果存储过程体仅仅只有一句话, begin end
可以省略
存储过程体中的每条sql语句的结尾要求必须加分号,存储过程的结尾可以使用 delimiter 重新设置.
语法:delimiter 结束标记
案例: delimiter $
CALL 存储过程名(实参列表);
案例1: 插入到admin表中五条记录
SELECT * FROM admin;
DELIMITER $
CREATE PROCEDURE myp1()
BEGIN
INSERT INTO admin(username,`password`)
VALUES('john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000');
END $
#调用
CALL myp1()$
in
模式参数的存储过程案例1:创建存储过程实现 根据女神名, 查询对应的男神信息
CREATE PROCEDURE myp2(IN beautyName VARCHAR(20))
BEGIN
SELECT bo.*
FROM boys bo
RIGHT JOIN beauty b ON bo.id = b.boyfriend_id
WHERE b.name=beautyName;
END $
#调用
CALL myp2('柳岩')$
案例2: 创建存储过程实现, 用户是否登录成功
CREATE PROCEDURE myp4(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
DECLARE result INT DEFAULT 0;#声明并初始化
SELECT COUNT(*) INTO result#赋值
FROM admin
WHERE admin.username = username
AND admin.password = PASSWORD;
SELECT IF(result>0,'成功','失败');#使用
END $
#调用
CALL myp3('张飞','8888')$
out
模式参数的存储过程案例1: 根据输入的女神名, 返回对应的男神名
CREATE PROCEDURE myp6(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20))
BEGIN
SELECT bo.boyname INTO boyname
FROM boys bo
RIGHT JOIN
beauty b ON b.boyfriend_id = bo.id
WHERE b.name=beautyName ;
END $
案例2: 根据输入的女神名, 返回对应的男神名和魅力值
CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT)
BEGIN
SELECT boys.boyname ,boys.usercp INTO boyname,usercp
FROM boys
RIGHT JOIN
beauty b ON b.boyfriend_id = boys.id
WHERE b.name=beautyName ;
END $
#调用
CALL myp7('小昭',@name,@cp)$
SELECT @name,@cp $
inout
模式参数的存储过程案例1: 传入a和b两个值, 最终a和b都翻倍并返回
CREATE PROCEDURE myp8(INOUT a INT ,INOUT b INT)
BEGIN
SET a=a*2;
SET b=b*2;
END $
#调用
SET @m=10$
SET @n=20$
CALL myp8(@m,@n)$
SELECT @m,@n $
语法: drop procedure 存储过程名
DROP PROCEDURE p1;
DROP PROCEDURE p2,p3;#不能一次删多个
DESC myp2;#不对
SHOW CREATE PROCEDURE myp2;
含义:一组预先编译好的SQL语句的集合,理解成批处理语句
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
存储过程: 可以有0个返回, 也可以有多个返回, 适合做批量插入或批量更新
函数: 有且仅有1 个返回, 适合做处理数据后返回一个结果
CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
函数体
END
注:
1.参数列表包含两部分: 参数名 参数类型
2.函数体: 肯定会有return
语句, 如果没有会报错;如果return
语句没有放在函数体的最后也不报错,但不建议return 值;
3.函数体中仅有一句话, 则可以省略begin end
4.使用delimiter
语句设置结束标记
SELECT 函数名(参数列表)
案例: 返回公司的员工个数
CREATE FUNCTION myf1() RETURNS INT
BEGIN
DECLARE c INT DEFAULT 0;#定义局部变量
SELECT COUNT(*) INTO c#赋值
FROM employees;
RETURN c;
END $
SELECT myf1()$
案例1:根据员工名, 返回它的工资
CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
BEGIN
SET @sal=0;#定义用户变量
SELECT salary INTO @sal #赋值
FROM employees
WHERE last_name = empName;
RETURN @sal;
END $
SELECT myf2('k_ing') $
案例2: 根据部门名,返回该部门的平均工资
CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
BEGIN
DECLARE sal DOUBLE ;
SELECT AVG(salary) INTO sal
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE d.department_name=deptName;
RETURN sal;
END $
SELECT myf3('IT')$
SHOW CREATE FUNCTION myf3;
DROP FUNCTION myf3;
案例: 创建函数, 实现传入两个float, 返回二者之和
CREATE FUNCTION test_fun1(num1 FLOAT,num2 FLOAT) RETURNS FLOAT
BEGIN
DECLARE SUM FLOAT DEFAULT 0;
SET SUM=num1+num2;
RETURN SUM;
END $
SELECT test_fun1(1,2)$
顺序、分支、循环
if
函数语法: if(条件, 值1, 值2)
功能: 实现双分支
应用在begin end
中或外面
case
结构情况1: 类似于switch
case 变量或表达式
when 值1 then 语句1;
when 值2 then 语句2;
...
else 语句n;
end
情况2:
case
when 条件1 then 语句1;
when 条件2 then 语句2;
...
else 语句n;
end
应用在begin end
中或外面
if
结构语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
....
else 语句n;
end if;
功能:类似于多重if
只能应用在begin end 中
案例1: 创建函数, 实现传入成绩: 如果成绩>90, 返回A;
如果成绩>80, 返回B;
如果成绩>60, 返回C;
否则返回D.
CREATE FUNCTION test_if(score FLOAT) RETURNS CHAR
BEGIN
DECLARE ch CHAR DEFAULT 'A';
IF score>90 THEN SET ch='A';
ELSEIF score>80 THEN SET ch='B';
ELSEIF score>60 THEN SET ch='C';
ELSE SET ch='D';
END IF;
RETURN ch;
END $
SELECT test_if(87)$
案例2: 创建存储过程, 如果工资<2000, 则删除;
如果5000>工资>2000, 则涨工资1000;
否则涨工资500
CREATE PROCEDURE test_if_pro(IN sal DOUBLE)
BEGIN
IF sal<2000 THEN DELETE FROM employees WHERE employees.salary=sal;
ELSEIF sal>=2000 AND sal<5000 THEN UPDATE employees SET salary=salary+1000 WHERE employees.`salary`=sal;
ELSE UPDATE employees SET salary=salary+500 WHERE employees.`salary`=sal;
END IF;
END $
CALL test_if_pro(2100)$
案例1: 创建函数, 实现传入成绩: 如果成绩>90, 返回A;
如果成绩>80, 返回B;
如果成绩>60, 返回C;
否则返回D.
CREATE FUNCTION test_case(score FLOAT) RETURNS CHAR
BEGIN
DECLARE ch CHAR DEFAULT 'A';
CASE
WHEN score>90 THEN SET ch='A';
WHEN score>80 THEN SET ch='B';
WHEN score>60 THEN SET ch='C';
ELSE SET ch='D';
END CASE;
RETURN ch;
END $
SELECT test_case(56)$
while, loop, repeat
循环控制:
iterate
类似于continue
, 继续, 结束本次循环, 继续下一次;
leave
类似于break
, 跳出, 结束当前所在的循环
while
语法:
[标签:] while 循环条件 do
循环体;
end while [标签];
联想:
while(循环条件){
循环体;
}
loop
语法:
[标签:]loop
循环体;
end loop [标签];
可以用来模拟简单的死循环
repeat
语法:
[标签:] repeat
循环体;
until 结束循环的条件
end repeat [标签];
案例: 批量插入, 根据次数插入到admin表中多条记录
DROP PROCEDURE pro_while1$
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<=insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'666');
SET i=i+1;
END WHILE;
END $
CALL pro_while1(100)$
类似于:
int i=1;
while(i<=insertcount){
//插入
i++;
}
leave
语句案例: 批量插入, 根据次数插入到admin表中多条记录, 如果次数>20则停止
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
a:WHILE i<=insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
IF i>=20 THEN LEAVE a;
END IF;
SET i=i+1;
END WHILE a;
END $
CALL test_while1(100)$
iterate
语句案例: 批量插入, 根据次数插入到admin表中多条记录, 只插入偶数次
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 0;
a:WHILE i<=insertCount DO
SET i=i+1;
IF MOD(i,2)!=0 THEN ITERATE a;
END IF;
INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
END WHILE a;
END $
CALL test_while1(100)$
类似于:
int i=0;
while(i<=insertCount){
i++;
if(i%2==0){
continue;
}
插入
}