前期的查询语言基本上都是敲就完事儿了,记的东西不太多,所以笔记不是很多,先做了这些.
听的课是杰个: 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(值...);
特点:
-
要求值的类型和字段的类型要一致或兼容(可以隐式转换)
-
字段的个数和顺序不一定与原始表的个数和顺序一致,但必须保证值和字段一一对应, 个数要一致!
-
假如表中有可以为null的字段,可以用两种方式插入null:
- 字段和值都省略
- 字段写上, 值使用null填充
-
字段名可以省略,默认所有列
语法2:
insert into 表名 set 字段 = 值, 字段 = 值 ...
两种方式的区别:
方法一支持一次插入多行:
insert into 表名[字段名...] values(值,...),(值,...)...
方法一支持子查询:
insert into 表名
查询语句(select...);
修改
-
修改单表的记录:
update 表名 set 字段=值,字段=值 [where 筛选条件];
-
修改多表的记录
update 表名 别名 left|right|inner join 表2 别名 on 连接条件 set 字段=值,字段=值 [where 筛选条件];
删除
-
使用delete
删除单表的记录
[补充]可以加limit
delete from 表名 [where 筛选条件] limit 数目;
删除级联(多表)的记录
delete 别名1,[别名2]
from 表1 别名1
left|right|inner join 表2 别名1
on 连接条件
[where 筛选条件];
-
使用truncate
truncate table 表名
-
truncate和delete的区别
- delete删除后, 如果再插入,自增长列从断点开始
truncate删除后, 如果再插入,自增长列从0开始 - delete可以加筛选条件, truncate不行
- truncate效率较高
- truncate没有返回值, delete可以返回首映先打个行数
- truncate不可以回滚, delete可以
- delete删除后, 如果再插入,自增长列从断点开始
DDL语言
库的管理
-
创建库
create database [if exists] 库名 character set utf8[字符集名];
-
删除库
drop database [if exists] 库名;
-
修改库(用的较少)
alter database 库名 character set utf8;
也可以修改库名,要先停止 mysql 服务, 然后去 data 文件夹改相应的文件夹的名字, 然后再启动 mysql服务就可以了,刷新就好了(但不是很稳定)
表的管理
创建表(⭐)
create table [if not exists] 表名(
字段名 字段类型 [约束],
...
字段名 字段类型 [约束]
);
修改表
-
添加列
alter table 表名 add column 列名 类型 [first \ after 字段名]; ## [first \ after 字段名]用来设置位置, 默认是最后一位
-
修改列的类型或约束
alter table 表名 modify column 列名 新类型 [新约束];
-
修改列名
alter table 表名 change column 旧列名 新列明 类型;
-
删除某列
alter table 表名 drop column 列名 ;
删除表
drop table [if exists] 表名;
复制表
-
复制表的结构
create table 表名 like [库名.]旧表; ## 库名.旧表使得表的复制可以跨库进行
-
复制表的结构及数据
create table 表名 select 查询列表 from 旧表 [where 筛选];
数据类型
数值型
-
整型: tinyint(1), smallint(2), mediumint(3), int(4), bigint(8)
- 都可以设置无符号和有符号, 默认有符号,通过unsigned设置无符号
- 超出范围
- 长度(显示的最大长度)可以不指定, 如果不够的话,则左边用0填充, 但要搭配zerofill, 且默认变为无符号类型
-
浮点型
- 定点数: decimal(M,D)
- 浮点数: float(M,D)
double(M,D) - 特点:
- M代表整数部分位数+小数部分位数, D代表小数部分位数
- 如果超出范围, 报错(并不会插入临界值)
- M和D都可以省略, 对于定点数, M默认为10, D默认为0;
- 精度要求较高一般使用定点型
字符型
char: 固定长度字符, char(M)最大不能超过M, 省略时默认为1
varchar: 可变长度的字符, varchar(M)最大不能超过M, M不可省略
binary, vbinary
enum, set, text, blob
日期型
year
date
time
datetime 8
timestamp 4 受时区影响,可以反映真实时间
常见约束
约束的含义: 一种限制, 用于限制表中的数据, 为了保证数据的准确和可靠;
分类:
- NOT NULL: 非空, 用于保证字段的值不为空; 例如:姓名或学号
- DEFAULT: 默认,用于保证该字段有默认值, 为了省事儿
- PRIMARY KEY: 主键, 用于保证该字段的值具有唯一性,且非空; 例如学号或员工编号(可以理解为主键字段代表了整行信息)
- UNIQUE: 唯一, 用于保证字段的值具有唯一性, 可以为空; 比如座位号
- CHECK(mysql不支持): 检查约束(Oracle可以)
- 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就行了就可以了
外键:
- 要求在从表设置外键关系
- 从表的外键列类型和主表的关联列的类型要求一致或兼容
- 主表的关联列必须是一个key(一般是主键或唯一键)
- 插入数据时, 先插入主表再插入从表;删表先删从表,建表先建主表
##联合主键测试
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 约束名] 约束类型(字段名);
-
添加非空约束(列级)
alter table syuinfo modify column seat varchar(20) not null; ## 去掉非空约束 alter table syuinfo modify column seat varchar(20) not null;
-
添加默认约束
alter table syuinfo modify column age int default 18;
-
添加主键约束
alter table syuinfo modify column id int primary key; ## 表级约束写法:(可以起名但没啥用) alter table syuinfo [constraint my_key_id] add primary key(id);
-
添加唯一
alter table syuinfo modify column seat int unique; ## 表级约束写法: alter table syuinfo add unique(seat);
-
添加外键
alter table syuinfo add foreign key(majorid) references major(id);
修改表时删除约束
-
删除非空约束
alter table modify column stu_name varchar(20) null; # 或者就默认情况 alter table modify column stu_name varchar(20);
-
删除默认约束
alter table modify colum age int;
-
删除主键约束
alter table stuinfo drop primary key;
-
删除唯一
alter table stuinfo drop index seat; show index from stuinfo;
-
删除外键
# 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');
#如此下去即可
标识列的特点
-
必须要和主键搭配使用吗?
不是, 和unique也可以, 是键就行
-
一个表至多有几个标识列? 一个!
-
标识列的类型必须是数值型(整型, 浮点型都可以)
-
标识列可以设置步长,也可以通过手动修改去设置起始值
修改表时添加标识列
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属性
-
原子性(Atomicity): 事务不可再拆分;
-
一致性(Consistency): 事务必须使数据库从一个一种状态变换到另一个一致性状态;
例如,张三丰目前余额1000,郭襄目前余额1000;张三丰给郭襄转账,俩人在银行里的余额一个是500, 一个是1500; (前后都必须保持2000块总额)
-
隔离性(Isolation):一个事务的执行, 不能被其他事务干扰;
-
持久性(Durability): 一个事物一旦被提交, 对数据库的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响.
事务的创建
隐式事务: 事务没有明显的开始或结束的标记, 例如update, insert, delete语句
show variables autocommit;
显式事务: 事务有明显的开始或结束的标记; 前提是必须要先设置自动提交功能为禁用, 但只针对当前会话有效
set autocommit = 0;
步骤:
-
开启事务
-
事务中的sql语句(增删改查)
-
结束事务(提交/回滚事务)
###开始事务 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)只是驻留在内存, 不会最终影响到数据
事务的隔离
对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没 有采取必要的隔离机制, 就会导致各种并发问题:
-
脏读: 对于两个事务 T1, T2: T1 读取了已经被 T2 更新但还没有被提交的字段(🍼 ). 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.
-
不可重复读: 对于两个事务T1, T2: T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.
-
幻读: 对于两个事务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语句的集和, 理解成批处理语句
好处: 提高代码重用性, 简化操作, 减少了和数据库服务器连接次数
-
创建
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;