MySQL初阶笔记

前期的查询语言基本上都是敲就完事儿了,记的东西不太多,所以笔记不是很多,先做了这些.
听的课是杰个: Mysql李玉婷老师. 非常喜欢李老师, 有趣简明
大致的话整个初阶有用15天左右听完敲完.

DQL语言

查询总结

语法如下:

select 查询列表 ##查询所有信息最好把列名都加上, 可读性高一嗲
from 表1 别名1
连接类型  join 表2 别名2
on 连接条件
where 筛选条件
group  by 分组列表
having 筛选
order by 排序列表
limit 起始条目索引,条目数;

执行顺序: 2 → \rarr 3 → \rarr 4 → \rarr 5 → \rarr 6 → \rarr 7 → \rarr 8 → \rarr 1 → \rarr 9

DML语言

插入

语法1:

insert into 表名(字段名...) values(值...);

特点:

  1. 要求值的类型和字段的类型要一致或兼容(可以隐式转换)

  2. 字段的个数和顺序不一定与原始表的个数和顺序一致,但必须保证值和字段一一对应, 个数要一致!

  3. 假如表中有可以为null的字段,可以用两种方式插入null:

    1. 字段和值都省略
    2. 字段写上, 值使用null填充
  4. 字段名可以省略,默认所有列

语法2:

insert into 表名 set 字段 = 值, 字段 = 值 ...

两种方式的区别:

​ 方法一支持一次插入多行:

insert into 表名[字段名...] values(值,...),(值,...)...

方法一支持子查询:

insert into 表名
查询语句(select...);

修改

  1. 修改单表的记录:

    update 表名 set 字段=值,字段=值 
    [where  筛选条件];
    
  2. 修改多表的记录

    update 表名 别名
    left|right|inner join 表2 别名
    on 连接条件
    set 字段=值,字段=值 
    [where  筛选条件];
    

删除

  1. 使用delete

    删除单表的记录

    [补充]可以加limit

    delete from 表名
    [where 筛选条件]
    limit 数目;
    

删除级联(多表)的记录

delete 别名1,[别名2]
from 表1 别名1
left|right|inner join 表2 别名1
on 连接条件
[where 筛选条件];

  1. 使用truncate

    truncate table 表名
    
    
  2. truncate和delete的区别

    1. delete删除后, 如果再插入,自增长列从断点开始
      truncate删除后, 如果再插入,自增长列从0开始
    2. delete可以加筛选条件, truncate不行
    3. truncate效率较高
    4. truncate没有返回值, delete可以返回首映先打个行数
    5. truncate不可以回滚, delete可以

DDL语言

库的管理

  1. 创建库

    create database [if exists] 库名 character set utf8[字符集名];
    
    
  2. 删除库

    drop database [if exists] 库名;
    
    
  3. 修改库(用的较少)

    alter database 库名 character set utf8;
    
    

    也可以修改库名,要先停止 mysql 服务, 然后去 data 文件夹改相应的文件夹的名字, 然后再启动 mysql服务就可以了,刷新就好了(但不是很稳定)

表的管理

创建表(⭐)
create table [if not exists] 表名(
    字段名 字段类型 [约束],
    ...
    字段名 字段类型 [约束]
);

修改表
  1. 添加列

    alter table 表名 add column 列名 类型 [first \ after 字段名];
    ## [first \ after 字段名]用来设置位置, 默认是最后一位
    
    
  2. 修改列的类型或约束

    alter table 表名 modify column 列名 新类型 [新约束];
    
    
  3. 修改列名

    alter table 表名 change column 旧列名 新列明 类型;
    
    
  4. 删除某列

    alter table 表名 drop column 列名 ;
    
    
删除表
drop table [if exists] 表名;

复制表
  1. 复制表的结构

    create table 表名 like [库名.]旧表;
    ## 库名.旧表使得表的复制可以跨库进行
    
    
  2. 复制表的结构及数据

    create table 表名 
    select 查询列表 from 旧表
    [where 筛选];
    
    

数据类型

数值型
  1. 整型: tinyint(1), smallint(2), mediumint(3), int(4), bigint(8)

    1. 都可以设置无符号和有符号, 默认有符号,通过unsigned设置无符号
    2. 超出范围
    3. 长度(显示的最大长度)可以不指定, 如果不够的话,则左边用0填充, 但要搭配zerofill, 且默认变为无符号类型
  2. 浮点型

    1. 定点数: decimal(M,D)
    2. 浮点数: float(M,D)
      double(M,D)
    3. 特点:
      1. M代表整数部分位数+小数部分位数, D代表小数部分位数
      2. 如果超出范围, 报错(并不会插入临界值)
      3. M和D都可以省略, 对于定点数, M默认为10, D默认为0;
      4. 精度要求较高一般使用定点型
字符型

char: 固定长度字符, char(M)最大不能超过M, 省略时默认为1

varchar: 可变长度的字符, varchar(M)最大不能超过M, M不可省略

binary, vbinary

enum, set, text, blob

日期型

year

date

time

datetime 8

timestamp 4 受时区影响,可以反映真实时间

常见约束

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

分类:

  1. NOT NULL: 非空, 用于保证字段的值不为空; 例如:姓名或学号
  2. DEFAULT: 默认,用于保证该字段有默认值, 为了省事儿
  3. PRIMARY KEY: 主键, 用于保证该字段的值具有唯一性,且非空; 例如学号或员工编号(可以理解为主键字段代表了整行信息)
  4. UNIQUE: 唯一, 用于保证字段的值具有唯一性, 可以为空; 比如座位号
  5. CHECK(mysql不支持): 检查约束(Oracle可以)
  6. FOREIGN KEY : 外键约束, 用于限制两个表的关系,用于保证当前表(从表)该字段的值必须来自于(或者说是引用)主表中关联列的值; 比如,employee表中的department_id必须是departments表中id的值,此时要在employee表中加一个外键约束

添加约束的时间:创建表时, 修改表时. 必要在数据添加之前

约束的添加分类:

​ 列级约束:

​ 六大约束都支持,但外键约束没有效果

​ 表级约束(脱离字段):

​ 除了非空\默认, 其他的都支持

举例

create table 表名(
	字段名 字段类型 列级约束,
    字段名 字段类型,
    表级约束
);

创建表时添加约束

​ 添加列级约束, 直接在字段名和类型后追加约束类型即可()可以添加多个

create table stuinfo(
	id int primary key,
    stu_name varchar(20) not null,
    gender char(1) check (gender = '男' or gender = '女'),##check也没啥子用
    seat int unique,
    majorid int references major(id) ## 其实这里并不起作用
); ##[foreign key references major(id)]在列级约束中不起作用

create table major(
	id int primary key,
    major_name varchar(20) not null
)



## 一些常用指令⭐
desc 表名;
show index from 表名;

添加表级约束:

drop table if exists stuinfo;

create table stuinfo(
	id int,
    stu_name varchar(20),
    gender char(1),
    age int,
    seat int,
    majorid int, 
    
    constraint pk primary key(id),#主键
    constraint uq unique(seat),#唯一键
    constraint ck check(gender in ('男','女')),#检查
    constraint fk_stuinfo_major foreign key(majorid) references major(id)# 外键
); 

create table major(
	id int primary key,
    major_name varchar(20) not null
)

完整语法:

​ 起名的过程可以省略, 主键默认名是primary, unique和外键默认名是字段名

外键起名时: fk _当前表名 _主表名

在各个字段的最下面:
[constraint 约束名] 约束类型(字段名)

通用写法:

​ primary key 类似都可以放在列级约束,外键放在表级约束

drop if exists stuinfo;

create table if not exists stuinfo(
	id int primary key,
    stu_name varchar(20) not null,
    gender char(1),
    age int default 18,
    seat int unique,
    majorid int, 
    
    constraint fk_stuinfo_major foreign key(majorid) references major(id)# 外键
); 

create table major(
	id int primary key,
    major_name varchar(20) not null
)

主键和唯一的对比:

区别主键唯一
唯一性
为空×
单表中可以有几个1多个
组合√但不推荐√但不推荐

组合: 比如将上表中的id和stu_name形成组合主键,那这两个里面只要有一个是不duplicate就行了就可以了

外键:

  1. 要求在从表设置外键关系
  2. 从表的外键列类型和主表的关联列的类型要求一致或兼容
  3. 主表的关联列必须是一个key(一般是主键或唯一键)
  4. 插入数据时, 先插入主表再插入从表;删表先删从表,建表先建主表
##联合主键测试
CREATE TABLE stuinfo(
    id INT,
    stu_name VARCHAR(20) NOT NULL,
    gender CHAR(1) CHECK (gender = '男' OR gender = '女'),
    seat INT UNIQUE,
    majorid INT,
    
    ##联合主键的约束写在这里
    PRIMARY KEY(id,stu_name),
    UNIQUE(seat),
    
    CONSTRAINT fk_stuinfo_majorid FOREIGN KEY(majorid) REFERENCES major(id)
    ); ##[foreign key references major(id)]在列级约束中不起作用
    
 SHOW INDEX FROM stuinfo;
 DESC stuinfo;
 
INSERT INTO stuinfo 
VALUES
  (1, 'John', '男', 11, 2), 
  (2, 'John', '女', NULL, 1),
  (2, 'Cici', '女', NULL, 1);
DELETE FROM stuinfo;
SELECT * FROM stuinfo;

修改表时添加约束

列级约束

alter table 表名 modify cloumn 字段名 字段类型 新约束;

表级约束

alter table 表名 [constraint 约束名] 约束类型(字段名);

  1. 添加非空约束(列级)

    alter table syuinfo modify column seat varchar(20) not null;
    ## 去掉非空约束
    alter table syuinfo modify column seat varchar(20) not null;
    
    
  2. 添加默认约束

    alter table syuinfo modify column age int default 18;
    
    
  3. 添加主键约束

    alter table syuinfo modify column id int primary key;
    
    ## 表级约束写法:(可以起名但没啥用)
    alter table syuinfo [constraint my_key_id] add primary key(id);
    
    
  4. 添加唯一

    alter table syuinfo modify column seat int unique;
    
    ## 表级约束写法:
    alter table syuinfo add unique(seat);
    
    
  5. 添加外键

    alter table syuinfo add foreign key(majorid) references major(id);
    
    
修改表时删除约束
  1. 删除非空约束

    alter table modify column stu_name varchar(20) null;
    # 或者就默认情况
    alter table modify column stu_name varchar(20);
    
    
  2. 删除默认约束

    alter table modify colum age int; 
    
    
  3. 删除主键约束

    alter table stuinfo drop primary key; 
    
    
  4. 删除唯一

    alter table stuinfo drop index seat;
    show index from stuinfo;
    
    
  5. 删除外键

    # CONSTRAINT fk_stuinfo_majorid FOREIGN KEY(majorid) REFERENCES major(id)
    
    alter table stuinfo drop  foreign key fk_stuinfo_majorid;
    
    
标识列

又称为自增长列,可以不用手动地插入值, 系统提供默认的序列

创建表时设置标识列

drop table if exists tabidentity;
create table tabidentity (
	id int primary key auto_increment,
    name varchar(20)
);

truncate table tabidentity;

insert into tabidentity values(null,'John');
##另一种方式
insert into tabidentity(name) values(null,'Lucy');
##又或者:
insert into tabidentity(name) values('Lucy');

查看自增长列

show variables like '%auto_increment';

设置自增长列的起始值和步长

#步长的修改
set auto_increment_increment = 3;
# 起始值需要手动改起
insert into tabidentity values(10,'John');
insert into tabidentity values(null,'John');
insert into tabidentity values(null,'John');
#如此下去即可

标识列的特点

  1. 必须要和主键搭配使用吗?

    不是, 和unique也可以, 是键就行

  2. 一个表至多有几个标识列? 一个!

  3. 标识列的类型必须是数值型(整型, 浮点型都可以)

  4. 标识列可以设置步长,也可以通过手动修改去设置起始值

修改表时添加标识列

drop table if exists tabidentity;
create table tabidentity (
	id int,
    name varchar(20)
);
alter table tabidentity modify column id int primary key auto_increment;

修改表时删除标识列

alter table tabidentity modify column id int;

TCL语言

Transaction Control Language 事务控制语言

事务: 一个或一组sql语句组成的执行单元, 全部执行or全部不执行, 每个sql语句都是相互依赖的. 整体的单元作为不可分割的整体,如果单元中的某条语句执行失败, 整个单元竟会回滚(撤销所有操作), 所有受到影响的数据将会返回事务开始以前的状态. 只有单元中的所有sql语句全部执行成功, 事务才被顺利执行.

存储引擎: 数据是用什么方式来存的(不同的技术存储在文件或内存中), innodb支持事务.

show engines;

事务的ACID属性

  1. 原子性(Atomicity): 事务不可再拆分;

  2. 一致性(Consistency): 事务必须使数据库从一个一种状态变换到另一个一致性状态;

    例如,张三丰目前余额1000,郭襄目前余额1000;张三丰给郭襄转账,俩人在银行里的余额一个是500, 一个是1500; (前后都必须保持2000块总额)

  3. 隔离性(Isolation):一个事务的执行, 不能被其他事务干扰;

  4. 持久性(Durability): 一个事物一旦被提交, 对数据库的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响.

事务的创建

隐式事务: 事务没有明显的开始或结束的标记, 例如update, insert, delete语句

show variables autocommit;

显式事务: 事务有明显的开始或结束的标记; 前提是必须要先设置自动提交功能为禁用, 但只针对当前会话有效

set autocommit = 0;

步骤:

  1. 开启事务

  2. 事务中的sql语句(增删改查)

  3. 结束事务(提交/回滚事务)

    ###开始事务
    set autocommit = 0
    start transaction;## 可选
    ###事务中的语句(select, delete, insert, update)
    ###结束事务
    commit;#提交事务
    rollback;#回滚
    
    

Example

drop table if exists account;
create table account (
	id int primary key auto_increment,
    usename varchar(20),
    balance double
);
insert into account(username,balance) values('张无忌',1000),('赵敏',1000);
##提交
set autocommit = 0;
start transaction;
update account set balance = 500 where username = '张无忌';
update account set balance = 1500 where username = '赵敏';
commit;

###回滚
set autocommit = 0;
start transaction;
update account set balance = 1000 where username = '张无忌';
update account set balance = 1000 where username = '赵敏';
rollback; ##没有提交(commit)只是驻留在内存, 不会最终影响到数据


事务的隔离

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没 有采取必要的隔离机制, 就会导致各种并发问题:

  1. 脏读: 对于两个事务 T1, T2: T1 读取了已经被 T2 更新但还没有被提交的字段(🍼 ). 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.

  2. 不可重复读: 对于两个事务T1, T2: T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.

  3. 幻读: 对于两个事务T1, T2: T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行(🍼 ). 之后, 如果 T1 再次读取同一个表, 就会多出几行.

    脏读针对字段, 幻读针对行

常用命令:
每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个全局变量 @@tx_isolation, 表示当前的事务隔离级别.
1.查看当前的隔离级别: SELECT @@tx_isolation;
2.设置当前 mySQL 连接的隔离级别:set transaction isolation level read committed; (read uncommitted/
3.设置数据库系统的全局的隔离级别:set global transaction isolation level read committed;

脏读不可重复读幻读
read uncommitted
read committed×
repeatable read(default)××
serializable×××

Savepoint

搭配rollback使用

set autocommit = 0;
start transcation;
delete from account where id = 1;
savepoint a;
delete from account;
rollback a;##回到savepoint那里

视图

含义: 虚拟表,和普通表一样用, 通过表动态生成的数据(只保存sql逻辑, 不保存查询结果), 有点类似于封装

# 查询姓张的同学的专业
# 不用视图查询时
select stu_name, major_name
from stuinfo as s
inner join major as m
on s.majorid = m.id
where stu_name like '张%';

#用视图时
create view test
as
select stu_name, major_name
from stuinfo as s
inner join major as m
on s.majorid = m.id;

select * from test where stu_name like '张%';

创建视图

create view 视图名
as 
查询语句; #一般是复杂查询语句

##1.查询姓名中包含a字符的员工名、部门名和工种信息 
DROP VIEW IF EXISTS view1; 
CREATE VIEW view1 AS
SELECT e.last_name AS en, d.department_name AS dn,j.job_title AS jn
FROM employees AS e
INNER JOIN departments AS d
ON e.department_id = d.department_id
INNER JOIN jobs AS j
ON e.job_id = j.job_id;	
SELECT * FROM view1 WHERE en LIKE '%a%';

##2.查询各部门的平均工资级别 
DROP VIEW IF EXISTS view2; 
CREATE VIEW view2 AS
SELECT AVG(salary) AS avs, d.department_name AS dn
FROM employees AS e
INNER JOIN departments AS d
ON e.department_id = d.department_id
GROUP BY dn;

SELECT avs, dn,grade_level FROM view2
INNER JOIN job_grades AS g
ON avs BETWEEN g.`lowest_sal` AND g.`highest_sal`;

##3.查询平均工资最低的部门信息
SELECT * FROM view2;
SELECT MIN(avs) FROM view2;
SELECT * FROM view2 ORDER BY avs LIMIT 1;

##4.查询平均工资最低的部门名和工资
DROP VIEW IF EXISTS v3; 
CREATE VIEW v3 AS
SELECT * FROM view2 ORDER BY avs ASC LIMIT 1; 
SELECT v3.*, d.*
FROM v3
INNER JOIN departments AS d
ON d.`department_name` = v3.dn;

变量

系统变量:全局变量及会话变量;由系统提供,不由用户定义,属于服务器层面

使用的语法

查看所有系统变量 show global variables | show [session] variables

查看满足条件的部分系统变量

包含特定字符的系统变量show global variables | [session] variables like ‘%char%’

查看指定系统变量的值

select @@global.系统变量名; select @@[session].系统变量名

为系统变量赋值

set global | [session]系统变量名 = 值;

set @@global | [session].系统变量名 = 值;

SHOW GLOBAL VARIABLES LIKE '%char%';

SELECT @@global.autocommit;##跨连接有效
SELECT @@tx_isolation;

全局变量: 服务器每次启动将为所有全局变量赋初始值, 针对所有会话(连接)有效, 但不能跨重启(重启的话会重新赋值);

会话变量

作用域:仅针对当前会话(连接)有效

SHOW SESSION VARIABLES;
SHOW SESSION VARIABLES like '%char%';
SHOW session VARIABLES LIKE '%char%';
set @@session.tx_isolation = 'read-uncommitted'##换连接就不起作用了

自定义变量

声明, 赋值, 使用(查看比较和运算)

用户变量: 作用域 :仅针对当前会话(连接)有效,同于会话变量的作用域

啥地方都可以用

#声明并初始化
set @用户变量名 := 值;#或
set @用户变量名 = 值; #不推荐,因为等号会用作比较
select @用户变量名 := 值; 

#赋值(更新用户变量的值)
###方法一 select or set
set @用户变量名 := 值;#或
set @用户变量名 = 值; #或
select @用户变量名 := 值; 
####Ex.
set @name = 'John';
set @name = 100;  ##这样都是可行的
###方法二 select into
select 字段 into 用户变量名 from 表;##必须查出来只有一个字段值

#####例
set @count = 1;
select count(*)into @count from employees;
SELECT @count;

局部变量

作用域: 仅在定位仪他的begin end中有效

必须是begin end中的第一句话

#声明
declare 变量名 变量类型;
declare 变量名 变量类型 default 值;#默认值需要和变量类型一致or兼容
#赋值
set 局部变量名 := 值;#或
set 局部变量名 = 值; #set这两个不用加@
select @局部变量名 := 值; #select这份必须加@
#使用
select 局部变量名;

set @m = 1;
set @n = 2;
set @sum = @m +@n;
select @sum;
#这样不对
declare m int default 1;
declare n int default 2;
declare sum;
set sum = m + n;

存储过程和函数

类似于Java中的方法

好处: 提高代码重用性, 简化操作

存储过程

含义: 一组预先编译好的SQL语句的集和, 理解成批处理语句

好处: 提高代码重用性, 简化操作, 减少了和数据库服务器连接次数

  1. 创建

    create procedure 存储过程名(参数列表)
    	begin
    		方法体
    	end
    
    

    参数列表,参数模式,参数名,参数类型

    参数模式 in out inout

    in: 用in修饰的参数可以作为输入(通常意义的参数), 需要调用方传入值
    out: 该参数可以作为输出(返回值)
    inout:该参入急需要传入值,又可以做为返回值

    存储过程体(方法体)里面只有一句话的话,begin end可以省略, 存储过程体里面的每一句都需要加’;’, 存储过程的结尾可以使用delimiter重新设置

    delimiter #
    create procedure test()
    begin
    insert into admin(username,`password`)
    values('john',0000),('Lily',1234),('Jack',1000);
    end #
    call test()# 
    
    
    Use girls;
    delimiter $
    CREATE PROCEDURE pro1 (IN beautyName VARCHAR (20)) 
    BEGIN
      SELECT 
        *
      FROM
        boys AS bo
        RIGHT JOIN beauty AS b 
          ON b.boyfriend_id = bo.id 
      WHERE b.name = beautyName;
     END $
    
    
     CALL pro2('张飞','99999')$
     
    CREATE PROCEDURE pro2(IN username VARCHAR (20),IN pass VARCHAR (20)) 
    BEGIN
    DECLARE a INT DEFAULT 0;
    SELECT COUNT(*) INTO a
     FROM admin
     WHERE admin.username = username
     AND admin.password = pass;
    SELECT IF(a>0,'Success','Failure');
    END$
    
    

    函数

    参数列表包含两部分, 参数名和参数类型;return可以不放在函数体的最尾

##创建函数
create function 函数名(参数列表) return 返回类型
begin
end $ 
##调用函数
select 函数名(参数列表)$

##无参有返回
##返回公司的员工个个数
DELIMITER $
CREATE FUNCTION pro2() RETURNS INT
BEGIN
DECLARE num INT;
SELECT COUNT(*) INTO num 
FROM employees;
RETURN num;
END$
SELECT pro2()$
##有参有返回
##根据员工名返回他的工资(使用用户变量)
CREATE FUNCTION fun1(empname VARCHAR(20)) RETURNS DOUBLE
BEGIN
SET @m =0 ;##定义用户变量
SELECT salary INTO @m
FROM employees
WHERE last_name = empname;
RETURN @m;
END$
SELECT fun1('kochhar')$
##根据部门名(员工名)返回平均工资or部门号
CREATE FUNCTION fun2 (depname VARCHAR (20)) RETURNS DOUBLE 
BEGIN
  DECLARE mean DOUBLE;
  SELECT 
    AVG(salary) INTO mean 
  FROM
    employees AS e
    INNER JOIN departments AS d
    ON d.department_id = e.department_id
  WHERE d.department_name = depname;
  RETURN mean;
END $
SELECT fun2('IT')$

查看函数

show create function func2;

删除函数

drop function func2;

流程控制结构

顺序结构

分支结构: 可从两条或多条路径里去执行

循环结构:满足一定条件的基础上重复执行一段代码

分支结构

if 简单双分支,类似于Java中的ifelse

if(expr1,expr2,expr3)如果1成立执行2不成立执行3,任何地方都可以用

case

可以作为表达式嵌套在其他语句中使用:可以放在任何地方;也可以作为独立的语句使用

情况1:类似于Java中的switch语句,一般用于实现等值判断

case 变量|表达式|字段
when 要判断的值 then 返回的值1[或语句1;]
when 要判断的值 then 返回的值2[或语句2;]
...
else then 返回的值n [或语句n;]
end

情况2:类似于Java中的多重if语句,一般用于实现区间判断

case 变量|表达式|字段
when 要判断的条件1 then 返回的值1[或语句1;]
when 要判断的条件2 then 返回的值2[或语句2;]
...
else then 返回的值n [或语句n;]
end

示例

## 创建存储过程根据成绩显示等级
CREATE PROCEDURE pro3 (IN score INT)
BEGIN 
	CASE
	WHEN score >100 THEN SELECT 'Wrong score';
	WHEN score >=90  THEN SELECT 'A';
	WHEN score >=80 THEN SELECT 'B';
	WHEN score >=60 THEN SELECT 'C';
	ELSE SELECT 'D';
	END CASE;
END$
CALL pro3(101)$

if结构 多重分支

if 要判断的条件1 then 或语句1;
else 要判断的条件2 then 或语句2;
...
else then 语句n;
end if;

循环控制语句

while, loop, repeat

循环控制:

iterate类似于continue, 结束本次循环, 继续下一次

leave类似于break, 跳出, 结束当前所在的循环

while
[标签:]while 循环条件 do  循环体;
end while;

loop
[标签:]loop 循环体;
end loop;

repeat

案例

#向admin表中批量插入数据
CREATE PROCEDURE pro12 (IN times INT) 
BEGIN
  DECLARE i INT DEFAULT 1;
  a: WHILE
    i < times DO 
    INSERT INTO admin(username, `password`) 
    VALUES
      (CONCAT('stu',i), '0000') ;
    SET i = i + 1;
  END WHILE a;
END $
##如果>=20就不加了
CREATE PROCEDURE pro12 (IN times INT) 
BEGIN
  DECLARE i INT DEFAULT 1;
  a: WHILE
    i < times DO
    IF i >=20 THEN LEAVE a;
    END IF; 
    INSERT INTO admin(username, `password`) 
    VALUES
      (CONCAT('stu',i), '0000') ;
    SET i = i + 1;
  END WHILE a;
END $

CREATE PROCEDURE pro12 (IN times INT) 
BEGIN
  DECLARE i INT DEFAULT 1;
  a: WHILE
    i < times DO
    SET i = i + 1;##如果不写到这的话就死循环了
    IF i%2 !=0 THEN iterate a;
    END IF; 
    INSERT INTO admin(username, `password`) 
    VALUES
      (CONCAT('stu',i), '0000') ;
  END WHILE a;
END $

drop procedure pro12$
truncate table admin;

/*已知一个表strcontent
      id自增长列;content varchar(20);
向该表插入指定个数的, 长度随机,起始位置随机的字符串
*/
delimiter $
DROP TABLE strcontent;
CREATE TABLE strcontent(
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(20)
);

#SET @FullString = ;
CREATE PROCEDURE pro13 (IN num INT) 
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE startindex INT DEFAULT 1 ;
DECLARE len INT DEFAULT 1;
DECLARE str VARCHAR(30) DEFAULT 'abcdefghijklmnopqrstuvwxyz';
a: WHILE i <= num DO
	SET startindex = CEILING(RAND()*26);
	SET len = CEILING(RAND()*(26-startindex));#26-starindex
	IF len>20 THEN ITERATE a; ##加一个判断会好一点, 不然会有空的行
	END IF;
	INSERT INTO strcontent(content) VALUES(SUBSTR(str,startindex, len));
	SET i = i+1;
	END WHILE a;
END $ 
call pro13(25)$
select * from strcontent$
DROP PROCEDURE pro13;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值