MySQL数据库学习笔记(三)

MySQL数据库笔记(三)

MySQL数据库笔记(一)
MySQL数据库笔记(二)

六、DML语言的学习 ★

DML(Data Manipulate Language):数据操作语言(如insert 、update、delete)

1、插入语句

语法:
insert into 表名(字段名,...)
values(值1,...);

特点:
1、字段类型和值类型一致或兼容,而且一一对应
2、可以为空的字段,可以不用插入值,或用null填充
3、不可以为空的字段,必须插入值
4、字段个数和值的个数必须一致
5、字段可以省略,但默认所有字段,并且顺序和表中的存储顺序一致

**方式一:**经典的插入

语法:
insert into 表名(列名,…) values(值1,…);

SELECT * FROM beauty;

1.插入的值的类型要与列的类型一致或兼容

INSERT INTO beauty(id,NAME,sex,borndate,phone,photo,boyfriend_id)
VALUES(13,'唐艺昕','女','1990-4-23','1898888888',NULL,2);

2.不可以为null的列必须插入值。可以为null的列如何插入值?

#方式一:
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');

3.列的顺序是否可以调换

INSERT INTO beauty(NAME,sex,id,phone)
VALUES('蒋欣','女',16,'110');

4.列数和值的个数必须一致

INSERT INTO beauty(NAME,sex,id,phone)
VALUES('关晓彤','女',17,'110');

5.可以省略列名,默认所有列,而且列的顺序和表中列的顺序一致

INSERT INTO beauty
VALUES(18,'张飞','男',NULL,'119',NULL,NULL);

方式二:
语法:
insert into 表名
set 列名=值,列名=值,…

INSERT INTO beauty
SET id=19,NAME='刘涛',phone='999';

两种方式大比较 ★
1、方式一支持插入多行,方式二不支持

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);

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;						

2、修改语句

1.修改单表的记录★

语法:
update 表名
set 列=新值,列=新值,...
where 筛选条件;

2.修改多表的记录

语法:
sql92语法:
update 表1 别名,表2 别名
set 列=值,...
where 连接条件
and 筛选条件;

sql99语法:
update 表1 别名
inner|left|right join 表2 别名
on 连接条件
set 列=值,...
where 筛选条件;

(1).修改单表的记录
案例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;

(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;

3、删除语句

方式一:delete

语法:
1、单表的删除【★】
delete from 表名 where 筛选条件
2、多表的删除
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 表名;

1、方式一:delete
(1).单表的删除
案例:删除手机号以9结尾的女神信息

DELETE FROM beauty WHERE phone LIKE '%9';
SELECT * FROM beauty;

(2).多表的删除
案例:删除张无忌的女朋友的信息

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`='黄晓明';

2、方式二:truncate语句
案例:将魅力值>100的男神信息删除

TRUNCATE TABLE boys ;

delete和truncate【面试题★】
1.delete 可以加where 条件,truncate不能加
2.truncate删除,效率高一丢丢
3.假如要删除的表中有自增长列,
如果用delete删除后,再插入数据,自增长列的值从断点开始,
而truncate删除后,再插入数据,自增长列的值从1开始。
4.truncate删除没有返回值,delete删除有返回值
5.truncate删除不能回滚,delete删除可以回滚.

SELECT * FROM boys;

DELETE FROM boys;
TRUNCATE TABLE boys;
INSERT INTO boys (boyname,usercp)
VALUES('张飞',100),('刘备',100),('关云长',100);

七、DDL语言的学习

DDL(Data Define Languge):数据定义语言(如create、drop、alter)

1、库和表的管理 √

(一)、库的管理
创建: create
修改: alter
删除: drop
1、库的创建

语法:
create database  [if not exists]库名;

案例:创建库Books

CREATE DATABASE IF NOT EXISTS books ;

2、库的修改

RENAME DATABASE books TO 新库名;

更改库的字符集

ALTER DATABASE books CHARACTER SET gbk;

3、库的删除

DROP DATABASE IF EXISTS books;

(二)、表的管理
1.表的创建 ★

语法:
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;

2.表的修改

语法
alter table 表名 add|drop|modify|change column 列名 【列类型 约束】;

①修改列名

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;

3.表的删除

DROP TABLE IF EXISTS book_author;

SHOW TABLES;

通用的写法:

DROP DATABASE IF EXISTS 旧库名;
CREATE DATABASE 新库名;

DROP TABLE IF EXISTS 旧表名;
CREATE TABLE  表名();

4.表的复制

INSERT INTO author VALUES
(1,'村上春树','日本'),(2,'莫言','中国'),(3,'冯唐','中国'),(4,'金庸','中国');

SELECT * FROM Author;
SELECT * FROM copy2;

1.仅仅复制表的结构

CREATE TABLE copy LIKE author;

2.复制表的结构+数据

CREATE TABLE copy2 
SELECT * FROM author;

3.只复制部分数据

CREATE TABLE copy3
SELECT id,au_name
FROM author 
WHERE nation='中国';

4.仅仅复制某些字段

CREATE TABLE copy4 
SELECT id,au_name
FROM author
WHERE 0;			

2、常见数据类型介绍 √

常见的数据类型

数值型:
	整型
	小数:
		定点数
		浮点数
字符型:
	较短的文本:char、varchar
	较长的文本:text、blob(较长的二进制数据)
日期型:

(一)、整型
分类:

tinyint、	smallint、	mediumint、	int/integer、	bigint
1	 			2			3			4				8

特点:

① 如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加unsigned关键字
② 如果插入的数值超出了整型的范围,会报out of range异常,并且插入临界值
③ 如果不设置长度,会有默认的长度
长度代表了显示的最大宽度,如果不够会用0在左边填充,但必须搭配zerofill使用!

1.如何设置无符号和有符号

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;

(二)、小数
分类:

1.浮点型
float(M,D)
double(M,D)
2.定点型
dec(M,D)
decimal(M,D)

特点:

①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');

(四)、日期型
分类:
date只保存日期
time 只保存时间
year只保存年
datetime保存日期+时间
timestamp保存日期+时间

特点:

			字节	范围		时区等的影响
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';         

3、常见约束 √

含义:一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性
分类:六大约束

NOT NULL:非空,用于保证该字段的值不能为空;比如姓名、学号等
DEFAULT:默认,用于保证该字段有默认值;比如性别
PRIMARY KEY:主键,用于保证该字段的值具有唯一性,并且非空;比如学号、员工编号等
UNIQUE:唯一,用于保证该字段的值具有唯一性,可以为空;比如座位号
CHECK:检查约束【mysql中不支持】;比如年龄、性别
FOREIGN KEY:外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值;
在从表添加外键约束,用于引用主表中某列的值;比如学生表的专业编号,员工表的部门编号,员工表的工种编号

添加约束的时机:
1.创建表时
2.修改表时

约束的添加分类:

列级约束:
	六大约束语法上都支持,但外键约束没有效果
	
表级约束:
	
	除了非空、默认,其他的都支持

主键和唯一的大对比:

	保证唯一性  是否允许为空    一个表中可以有多少个   是否允许组合
主键	√			×			至多有1个           	√,但不推荐
唯一	√			√			可以有多个          	√,但不推荐

外键:

1、要求在从表设置外键关系
2、从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求
3、主表的关联列必须是一个key(一般是主键或唯一)
4、插入数据时,先插入主表,再插入从表
删除数据时,先删除从表,再删除主表

CREATE TABLE 表名(
	字段名 字段类型 列级约束,
	字段名 字段类型,
	表级约束
)

(一)、创建表时添加约束
1.添加列级约束
语法:直接在字段名和类型后面追加 约束类型即可。
只支持:默认、非空、主键、唯一

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;

2.添加表级约束
语法:在各个字段的最下面
【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)

);
(二)、修改表时添加约束
1、添加列级约束
alter table 表名 modify column 字段名 字段类型 新约束;

2、添加表级约束
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;

3.添加非空约束

ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NOT NULL;

4.添加默认约束

ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;

5.添加主键

#①列级约束
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
#②表级约束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);

6.添加唯一

#①列级约束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
#②表级约束
ALTER TABLE stuinfo ADD UNIQUE(seat);

7.添加外键

ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id); 

(三)、修改表时删除约束
1.删除非空约束

ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;

2.删除默认约束

ALTER TABLE stuinfo MODIFY COLUMN age INT ;

3.删除主键

ALTER TABLE stuinfo DROP PRIMARY KEY;

4.删除唯一

ALTER TABLE stuinfo DROP INDEX seat;

5.删除外键

ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;

SHOW INDEX FROM stuinfo;
4、标识列

标识列:又称为自增长列,可以不用手动的插入值,系统提供默认的序列值
特点:
1、标识列必须和主键搭配吗?不一定,但要求是一个key
2、一个表可以有几个标识列?至多一个!
3、标识列的类型只能是数值型
4、标识列可以通过 SET auto_increment_increment=3;设置步长
可以通过 手动插入值,设置起始值
创建表时设置标识列

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;

八、TCL语言的学习

事务和事务处理

TCL(Transaction Control Language): 事务控制语言

事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。

案例:转账

张三丰  1000
郭襄	1000
update 表 set 张三丰的余额=500 where name='张三丰'
意外
update 表 set 郭襄的余额=1500 where name='郭襄'

事务的特性:ACID

原子性(Atomicity):一个事务不可再分割,要么都执行要么都不执行
一致性(Consistency):一个事务执行会使数据从一个一致状态切换到另外一个一致状态
隔离性(Isolation):一个事务的执行不受其他事务的干扰
持久性(Durability):一个事务一旦提交,则会永久的改变数据库的数据.

事务的创建
1.隐式事务:事务没有明显的开启和结束的标记
比如insert、update、delete语句

delete from 表 where id =1;

2.显式事务:事务具有明显的开启和结束的标记
前提:必须先设置自动提交功能为禁用

set autocommit=0;

步骤1:开启事务
set autocommit=0;
start transaction;可选的
步骤2:编写事务中的sql语句(select insert update delete)
语句1;
语句2;
...
步骤3:结束事务
commit;提交事务
rollback;回滚事务

savepoint 节点名;设置保存点

事务的隔离级别:

	  				脏读		不可重复读	幻读
read uncommitted:	√				√		√
read committed:  	×				√		√
repeatable read: 	×				×		√
serializable	  	×				×       ×

mysql中默认 第三个隔离级别 repeatable read
oracle中默认第二个隔离级别 read committed

查看隔离级别
select @@tx_isolation;

设置隔离级别
set session|global transaction isolation level 隔离级别;

1.演示事务的使用步骤
#开启事务

SET autocommit=0;
START TRANSACTION;

#编写一组事务的语句

UPDATE account SET balance = 1000 WHERE username='张无忌';
UPDATE account SET balance = 1000 WHERE username='赵敏';

#结束事务

ROLLBACK;
commit;

SELECT * FROM account;

2.演示事务对于delete和truncate的处理的区别

SET autocommit=0;
START TRANSACTION;

DELETE FROM account;
ROLLBACK;

3.演示savepoint 的使用

SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点

SELECT * FROM account;                

九、视图的讲解 √

视图:虚拟表,和普通表一样使用;mysql5.1版本出现的新特性,是通过表动态生成的数据
比如:舞蹈班和普通班级的对比

		创建语法的关键字		是否实际占用物理空间		使用
视图	create view			只是保存了sql逻辑		增删改查,只是一般不能增删改
表		create table		保存了数据				增删改查

案例:查询姓张的学生名和专业名

SELECT stuname,majorname
FROM stuinfo s
INNER JOIN major m ON s.`majorid`= m.`id`
WHERE s.`stuname` LIKE '张%';

CREATE VIEW v1
AS
SELECT stuname,majorname
FROM stuinfo s
INNER JOIN major m ON s.`majorid`= m.`id`;

SELECT * FROM v1 WHERE stuname LIKE '张%';

1、创建视图

语法:

create view 视图名
as
查询语句;

USE myemployees;
1.查询姓名中包含a字符的员工名、部门名和工种信息

#①创建
CREATE VIEW myv1
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 myv1 WHERE last_name LIKE '%a%';

2.查询各部门的平均工资级别

#①创建视图查看每个部门的平均工资
CREATE VIEW myv2
AS
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id;
#②使用
SELECT myv2.`ag`,g.grade_level
FROM myv2
JOIN job_grades g
ON myv2.`ag` BETWEEN g.`lowest_sal` AND g.`highest_sal`;

3.查询平均工资最低的部门信息

SELECT * FROM myv2 ORDER BY ag LIMIT 1;

4.查询平均工资最低的部门名和工资

CREATE VIEW myv3
AS
SELECT * FROM myv2 ORDER BY ag LIMIT 1;

SELECT d.*,m.ag
FROM myv3 m
JOIN departments d
ON m.`department_id`=d.`department_id`;

2、视图的修改

方式一:

create or replace view  视图名
as
查询语句;

SELECT * FROM myv3 

CREATE OR REPLACE VIEW myv3
AS
SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;

方式二:
语法:

alter view 视图名
as 
查询语句;

ALTER VIEW myv3
AS
SELECT * FROM employees;

3、删除视图

语法:drop view 视图名,视图名,…;

DROP VIEW emp_v1,emp_v2,myv3;

4、查看视图

DESC myv3;

SHOW CREATE VIEW myv3;

5、视图的更新

CREATE OR REPLACE VIEW myv1
AS
SELECT last_name,email,salary*12*(1+IFNULL(commission_pct,0)) "annual salary"
FROM employees;

CREATE OR REPLACE VIEW myv1
AS
SELECT last_name,email
FROM employees;

SELECT * FROM myv1;
SELECT * FROM employees;

1.插入

INSERT INTO myv1 VALUES('张飞','zf@qq.com');

2.修改

UPDATE myv1 SET last_name = '张无忌' WHERE last_name='张飞';

3.删除

DELETE FROM myv1 WHERE last_name = '张无忌';

具备以下特点的视图不允许更新

#①包含以下关键字的sql语句:分组函数、distinct、group  by、having、union或者union all
CREATE OR REPLACE VIEW myv1
AS
SELECT MAX(salary) m,department_id
FROM employees
GROUP BY department_id;

SELECT * FROM myv1;

更新
UPDATE myv1 SET m=9000 WHERE department_id=10;

#②常量视图
CREATE OR REPLACE VIEW myv2
AS
SELECT 'john' NAME;
SELECT * FROM myv2;

#更新
UPDATE myv2 SET NAME='lucy';

#③Select中包含子查询
CREATE OR REPLACE VIEW myv3
AS
SELECT department_id,(SELECT MAX(salary) FROM employees) 最高工资
FROM departments;

#更新
SELECT * FROM myv3;
UPDATE myv3 SET 最高工资=100000;

#④join
CREATE OR REPLACE VIEW myv4
AS
SELECT last_name,department_name
FROM employees e
JOIN departments d
ON e.department_id  = d.department_id;

#更新
SELECT * FROM myv4;
UPDATE myv4 SET last_name  = '张飞' WHERE last_name='Whalen';
INSERT INTO myv4 VALUES('陈真','xxxx');

#⑤from一个不能更新的视图
CREATE OR REPLACE VIEW myv5
AS
SELECT * FROM myv3;

#更新
SELECT * FROM myv5;
UPDATE myv5 SET 最高工资=10000 WHERE department_id=60;

#⑥where子句的子查询引用了from子句中的表
CREATE OR REPLACE VIEW myv6
AS
SELECT last_name,email,salary
FROM employees
WHERE employee_id IN(
	SELECT  manager_id
	FROM employees
	WHERE manager_id IS NOT NULL
);

#更新
SELECT * FROM myv6;
UPDATE myv6 SET salary=10000 WHERE last_name = 'k_ing';

十、变量

分类

系统变量:
	全局变量
	会话变量
自定义变量:
	用户变量
	局部变量

1、系统变量

说明:变量由系统定义,不是用户定义,属于服务器层面
【注意】:全局变量需要添加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】系统变量名=值;

1、全局变量
作用域:针对于所有会话(连接)有效,但不能跨重启

#①查看所有全局变量
SHOW GLOBAL VARIABLES;
#②查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';
#③查看指定的系统变量的值
SELECT @@global.autocommit;
#④为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;

2、会话变量
作用域:针对于当前会话(连接)有效

#①查看所有会话变量
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';

2、自定义变量

说明:变量由用户自定义,而不是系统提供的
使用步骤:
1、声明
2、赋值
3、使用(查看、比较、运算等)
1、用户变量
作用域:针对于当前会话(连接)有效,作用域同于会话变量

#赋值操作符:=或:=
#①声明并初始化
SET @变量名=值;
SET @变量名:=值;
SELECT @变量名:=值;

#②赋值(更新变量的值)
#方式一:
	SET @变量名=值;
	SET @变量名:=值;
	SELECT @变量名:=值;
#方式二:
	SELECT 字段 INTO @变量名
	FROM 表;
	
#③使用(查看变量的值)
SELECT @变量名;

2、局部变量
作用域:仅仅在定义它的begin end块中有效;应用在 begin end中的第一句话

#①声明
DECLARE 变量名 类型;
DECLARE 变量名 类型 【DEFAULT 值】;

#②赋值(更新变量的值)

#方式一:
	SET 局部变量名=值;
	SET 局部变量名:=值;
	SELECT 局部变量名:=值;
#方式二:
	SELECT 字段 INTO 具备变量名
	FROM 表;

#③使用(查看变量的值)
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;

3、用户变量和局部变量的对比

			作用域				定义位置					语法
用户变量		当前会话				会话的任何地方			加@符号,不用指定类型
局部变量		定义它的BEGIN END中	BEGIN END的第一句话		一般不用加@,需要指定类型                    

十一、存储过程和函数

存储过程和函数:类似于java中的方法
好处:1、提高代码的重用性;2、简化操作

1、存储过程

含义:一组预先编译好的SQL语句的集合,理解成批处理语句
好处:
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
(一)、创建语法

CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
	存储过程体(一组合法的SQL语句)
END

【注意】
1、参数列表包含三部分:参数模式 参数名 参数类型
举例:
in stuname varchar(20)

参数模式:

in:该参数可以作为输入,也就是该参数需要调用方传入值
out:该参数可以作为输出,也就是该参数可以作为返回值
inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值

2、如果存储过程体仅仅只有一句话,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()$

2.创建带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')$

3.创建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$

4.创建带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;

2、函数

含义:一组预先编译好的SQL语句的集合,理解成批处理语句
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率

区别
存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新
函数:有且仅有1 个返回,适合做处理数据后返回一个结果

(一)、创建语法

CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
	函数体
END

【注意】:
1.参数列表 包含两部分:参数名 参数类型
2.函数体:肯定会有return语句,如果没有会报错;如果return语句没有放在函数体的最后也不报错,但不建议
3.函数体中仅有一句话,则可以省略begin end
4.使用 delimiter语句设置结束标记
(二)、调用语法

SELECT 函数名(参数列表)

1.无参有返回
案例:返回公司的员工个数

CREATE FUNCTION myf1() RETURNS INT
BEGIN
	DECLARE c INT DEFAULT 0;#定义局部变量
	SELECT COUNT(*) INTO c#赋值
	FROM employees;
	RETURN c;
END $

SELECT myf1()$

2.有参有返回
案例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)$

十二、流程控制结构

流程控制结构:顺序、分支、循环

1、分支结构

1.if函数
语法:if(条件,值1,值2)
功能:实现双分支
应用在begin end中或外面
2.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 中或外面
3.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)$

2、循环结构

分类
while、loop、repeat

循环控制
iterate类似于 continue,继续,结束本次循环,继续下一次
leave 类似于 break,跳出,结束当前所在的循环

1.while
语法:

【标签:】while 循环条件 do
	循环体;
end while【 标签】;

联想:

while(循环条件){

	循环体;
}

2.loop
语法:

【标签:】loop
	循环体;
end loop 【标签】;
可以用来模拟简单的死循环

3.repeat
语法:

【标签:】repeat
	循环体;
until 结束循环的条件
end repeat 【标签】;

(1).没有添加循环控制语句
案例:批量插入,根据次数插入到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++;
}

(2).添加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)$

(3).添加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;
	}
	插入
}
*/
(笔记整理自李玉婷老师的MySQL课程)
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值