mysql --- sql 语句大全 || 索引 || 储存函数+过程+触发器+视图

序章:MySQL如何优化

1、优化方案

1、添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
2、SQL语句优化
3、分表技术(水平分割、垂直分割)
4、读写[写: update/delete/add]分离
5、存储过程 [模块化编程,可以提高速度]
6、对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]
7、mysql服务器硬件升级
8、定时的去清除不需要的数据,定时进行碎片整理(MyISAM)

2、数据库设计三大范式

表的设计合理化(符合3NF)
1、第一范式:原子性约束,不可再分解(字段内容,如地址,可拆分成省/市/区)
-------1NF是对属性的原子性约束,要求属性(列)具有原子性,不可再分解;(只要是关系型数据库都满足1NF)
2、第二范式:惟一性约束 (id主键)
-------2NF是对记录的惟一性约束,表中的记录是唯一的, 就满足2NF, 通常我们设计一个主键来实现,主键不能包含业务逻辑。
3、第三范式:子段冗余性的约束 (重复数据拆分成多个表保存)
-------3NF是对字段冗余性的约束,它要求字段没有冗余。 没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余

3、慢查询

慢查询的作用?
------- 查询慢的语句会已日志的方式记录下来,通过日志记录查看哪些sql 查询慢,在调优查询慢的语句
什么是慢查询?
------ MySQL默认10秒内没有响应SQL结果,则为慢查询
------ 可以去修改MySQL慢查询默认时间

--查询慢查询时间
show variables like 'long_query_time';
--修改慢查询时间
set long_query_time=1; ---但是重启mysql之后,long_query_time依然是my.ini中的值

在默认情况下,我们的mysql不会记录慢查询,需要在启动mysql时候,指定记录慢查询才可以,在 my.ini 中指定,

一、查询sql

本文表sql+数据,https://download.csdn.net/download/qq_41463655/10991818

一般查询

1、简单查询

语法:Select * |列名 from 表名

   Select * from ws_user;                        #查询所有
    Select username from ws_user;                 #只查询username列
    Select username,password from ws_user;        #只查询username,password列

2、别名

语法:Select 列名 别名… from 表名

Select username '昵称',password '密码' from ws_user;  #使用别名

3、去除重复数据

语法:Select distinct *|列名 from 表名

Select distinct password from ws_user;         #去除重复数据,所有列数据相同才去除

4、四则运算

如下,需加表的的别名 或 表.字段名称

`select m.rank*12  from ws_menu m;`            # 使用四则运算 + - * /
`select * from ws_menu m where m.rank > 100;`  # 只查询 rank字段大于100的

5、非空判断

select * from ws_menu m where m.rank is not null; # 查询 rank 不为空的
select * from ws_menu m where m.rank is null;     # 查询 rank 为空的

6、where and or 连接查询 及 非空大于小于判断

# 查询 rank 不为空 且 > 500 的    # and   
select * from ws_menu m where m.rank is not null and  m.rank > 500; 

# 查询 rank > 500  且小于 1500 的
select * from ws_menu m where m.rank >500 and m.rank < 1500;
select * from ws_menu m where m.rank >= 500 and m.rank <= 1500;

# 查询 rank 不为空 或者 rank > 500 的 (满足其中一个 or)
select * from ws_menu m where m.rank is not null or  m.rank > 500;

# 查询 rank > 500  或者小于 1500 的
select * from ws_menu m where m.rank >500 or m.rank < 1500;

7、时间及排序

时间区间查询 between 升序排序:order by o.start_time asc

select * from ws_order o where o.start_time between '2017-05-06' and '2019-06-6' order by o.start_time asc;

时间比较查询 > < 降序排序:order by o.start_time desc

select * from ws_order o where o.start_time > '2017-05-06' and o.start_time <'2019-06-6' order by o.start_time desc;
下列所有 sql ,ws_order o 为表名 , o.start_time 为时间字段

8、指定查询 in,not in

select * from ws_menu where menu_id = 1;                 # 查询id=1的;
select * from ws_menu where text = '用户管理';           # 使用字符串查询

select * from ws_menu where menu_id = 1 or menu_id = 2;  # 同时查询id=1 和 2 的;
select * from ws_menu where menu_id in(1,2);             # 同时查询id=1 和 2 的;  
select * from ws_menu where text in('用户管理','部门管理'); 

select * from ws_menu where menu_id not in(1);        # 查询除id不等于1的;
select * from ws_menu where menu_id not in(1,2);      # 查询除id不等于1 和 2 的;

9、不等于表达式 <> !=

select * from ws_menu where menu_id != 1;   # 查询除id不等于1的;
select * from ws_menu where menu_id <> 1;   # 查询除id不等于1的;

10、模糊查询 like _ %

select * from ws_menu m where m.text like '_户管理';  # 匹配一个任意字段内容
select * from ws_menu m where m.text like '__管理';   # 匹配两个任意字段
select * from ws_menu m where m.text like '%理';      # 匹配无数个任意字段
select * from ws_menu m where m.text like '%管%';     # 中间带管字的全部查询处理

11、排序 order by 排序字段名 asc | desc

select * from ws_menu m order by m.rank asc;  # 降序,新数据在后
select * from ws_menu m order by m.rank desc; # 升序,新数据在前

# 可以指定多个排序字段,优先指定前一个,前一个字段相同或空根据第二个字段排序
select * from ws_menu m order by m.rank asc,m.menu_id asc; 
select * from ws_menu m order by m.rank asc,m.menu_id desc; 

时间查询

查询48 小时内的数据
select * from ws_order o where o.start_time >=(NOW() - interval 24 hour)
今天,0点开始
select * from ws_order o where to_days(o.start_time) = to_days(now());
昨天到现在
SELECT * FROM ws_order o WHERE TO_DAYS( NOW( ) ) - TO_DAYS(o.start_time) <= 1;
7天
SELECT * FROM ws_order o where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(o.start_time);
近30天
SELECT * FROM ws_order o where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(o.start_time);
本月
SELECT * FROM ws_order o WHERE DATE_FORMAT(o.start_time, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' );
上一月
SELECT * FROM ws_order o WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format(o.start_time, '%Y%m' ) ) =1;
查询本季度数据
select * from ws_order o where QUARTER(o.start_time)=QUARTER(now());
查询上季度数据
select * from ws_order o where QUARTER(o.start_time)=QUARTER(DATE_SUB(now(),interval 1 QUARTER));
查询本年数据
select * from ws_order o where YEAR(o.start_time)=YEAR(NOW());
查询上年数据
select * from ws_order o where year(o.start_time)=year(date_sub(now(),interval 1 year));
查询当前这周的数据
SELECT * FROM ws_order o WHERE YEARWEEK(date_format(o.start_time,'%Y-%m-%d')) = YEARWEEK(now());
查询上周的数据,及上上周
SELECT * FROM ws_order o  WHERE YEARWEEK(date_format(o.start_time,'%Y-%m-%d')) = YEARWEEK(now())-1;
SELECT * FROM ws_order o  WHERE YEARWEEK(date_format(o.start_time,'%Y-%m-%d')) = YEARWEEK(now())-2;
查询当前月份的数据
select * from ws_order o  where date_format(o.start_time,'%Y-%m')=date_format(now(),'%Y-%m')
查询距离当前现在6个月的数据
select * from ws_order o  where o.start_time between date_sub(now(),interval 6 month) and now();
查询上个月的数据
select * from ws_order o  where date_format(o.start_time,'%Y-%m')=date_format(DATE_SUB(curdate(), INTERVAL 1 MONTH),'%Y-%m');

12、多表查询

语法:SELECT {DISTINCT} *|列名… FROM 表名 别名,表名1 别名
{WHERE 限制条件 ORDER BY 排序字段 ASC|DESC…}

1、双表查询

# 双表查询(商品订单+订单详情(笛卡尔积,数据多+乱))
select * from ws_order,ws_order_detail;    

 #去掉笛卡尔积,只留下有关系的数据
select * from ws_order o,ws_order_detail d where o.order_id = d.order_id; 

# 查询订单号,下单时间,价格,数量及总价格
select o.order_no,o.start_time,d.order_price,d.order_num,d.oeder_money from ws_order o,ws_order_detail d where o.order_id = d.order_id; 

2、三表查询(商品订单+订单详情+订单日志)

select * from ws_order o,ws_order_detail d,ws_order_log l 
where o.order_id = d.order_id and o.order_id = l.order_id;  

# 只看 1429 的数据
select * from ws_order o,ws_order_detail d,ws_order_log l 
where o.order_id = d.order_id and o.order_id = l.order_id and o.order_id =1429;  

# 只看 1429 的具体数据
select o.order_no,d.oeder_money,l.log_notes,log_time
from ws_order o,ws_order_detail d,ws_order_log l 
where o.order_id = d.order_id and o.order_id = l.order_id and o.order_id =1429;  

3、交叉查询 cross join

交叉查询  cross join
select * from ws_order cross join ws_order_detail; #产生笛卡尔积

## 交叉查询 using子句 (类似于连接条件查询)
select * from ws_order cross join ws_order_detail using(order_id) where order_id = 1308;

## 交叉查询 on子句 (),相当于 where
select * from ws_order o cross join ws_order_detail d on o.order_id = d.order_id;

## 上一句同下
select * from ws_order o,ws_order_detail d where o.order_id = d.order_id; 

4、左连接 left join

select * from ws_order o left join ws_order_detail d on o.order_id = d.order_id;

5、左连接 left join

select * from ws_order o right join ws_order_detail d on o.order_id = d.order_id;

13、统计查询

1、数量 count()

select count(*) from ws_menu;          ## 不建议使用*
select count(m.rank) from ws_menu m;   ## 随意指定一列无空字段的数据

2、取最小值 min()

select min(m.rank) from ws_menu m; 

3、 取最大值 max()

select max(m.rank) from ws_menu m; 

4、取平均值 avg()

select avg(m.rank) from ws_menu m; 

5、取想加的和

select sum(m.rank) from ws_menu m; 

14、分组统计 group by

#注意:只有分组条件在结果集中是重复的分组才有意义

语法:SELECT * |列名 FROM 表名
{WEHRE 查询条件}
{GROUP BY 分组字段}
ORDER BY 列名1 ASC|DESC,列名2…ASC|DESC

1、查询根据 type 类别分组, 返回值与分组值要相同,不能出现其他字段

select o.type from ws_order o group by o.type;   

2、根据 type 类别分组并计算数量

select o.type,count(type) from ws_order o group by o.type;  

3、根据 type 类别分组并计算数量,且类别下的数量 > 1 的(having)

select o.type,count(type) from ws_order o group by o.type having count(type) > 1;   

4、查询每个类别下价格最高的商品(type,类别)

select o.type,max(d.order_price) from ws_order o,ws_order_detail d where o.order_id = d.order_id group by o.type;

5、查询每个类别下价格最低的商品

select o.type,min(d.order_price) from ws_order o,ws_order_detail d where o.order_id = d.order_id group by o.type;

6、查询每个类别下商品的平均价格

select o.type,avg(d.order_price) from ws_order o,ws_order_detail d where o.order_id = d.order_id group by o.type;

7、查询每个类别下商品的平均价格 且大于 2700 的(having)

select o.type,avg(d.order_price) from ws_order o,ws_order_detail d where o.order_id = d.order_id group by o.type
having avg(d.order_price) > 2700;

8、查询每个类别下商品的的总价格之和

select o.type,sum(d.oeder_money) from ws_order o,ws_order_detail d where o.order_id = d.order_id group by o.type;

15、子查询

1、查询比 id = 1310 的商品价格高的所有数据

# 子sql 返回 1310 的价格

select * from ws_order_detail o where o.order_price > (
    select o1.order_price from ws_order_detail o1 where o1.order_detail_id = 1310
);

2、查询比 id = 1310 的商品价格高且订单数量比 id = 1310 多的所有数据

# 子sql 一返回 1310 的价格
# 子sql 二返回 1310 的订单数量

select * from ws_order_detail o 
 where o.order_price > (
    select o1.order_price from ws_order_detail o1 where o1.order_detail_id = 1310 
		) 
 and o.remain_num > (
    select o2.remain_num from ws_order_detail o2 where o2.order_detail_id = 1310 
		);

3、子sql 返回的是一张表,根据 type 统计的统计表,

# typenum 是统计的数量字段名
# 统计分组数量 大于1 条以上的

select * from ws_order o,(select o1.type,count(type) typenum from ws_order o1 group by o1.type) o1
where o.type = o1.type 
and o1.typenum > 1;

16、in 同时查询(list)

1、查询所有类别下的所有最低价格的商品

# 子sql:查询所有类别下的每个类别最低价的商品集
select * from ws_order_detail d 
where d.order_price in (
  select min(d1.order_price) minprice from ws_order_detail d1 where d1.order_price group by d1.order_price
	);

2、查询有密码的所有用户(无密码的 not in)

   # 子sql 去重查询所有sql
    select * from ws_user u where u.password in(
         select distinct password from ws_user u1 where u.password = u1.password
    );

3、查询无密码的所有用户(有密码的不要not)

# 子sql 去重查询所有sql
# 同上(not exists 假,exists 真)

    select * from ws_user u where not exists(
      select * from ws_user u1 where u.password = u1.password 
    );

4、union 对两个结果集进行并集操作,都查询出来合并(不包括重复数据)

select * from ws_order_detail o where o.order_price > 2400
union
select * from ws_order_detail o where o.order_price > 2800;

5、union all 对两个结果集进行并集操作,都查询出来合并(包括重复数据)

select * from ws_order_detail o where o.order_price > 2400
union all
select * from ws_order_detail o where o.order_price > 2400;

分页查询sql 及优化

1、查询索引 x 后的 y 条数据

select * from ws_user limit 8,2;

2、带排序的分页

select * from ws_user order by user_id limit 8,2;

3、带条件的分页

select * from ws_user where 1=1 limit 8,2;

4、优化分页查一(使用子sql,只适用于id自增的表)

# 子sql 开始获取开始的第一条数据的id
# 查询大于该id 的后一百条数据
select * from ws_user u where u.user_id >=(select user_id from ws_user limit 5,1) limit 100;

5、优化分页二(范围查询,可以通过页数和记录数计算范围)

# 查询id 1到1000范围内的,从1开始后的100条数据
select * from ws_user u where u.user_id between 1 and 1000 limit 100;

6、优化分页三(范围查询,可以通过页数和记录数计算范围)

# 查询id从1开始后的100条数据
select * from ws_user where user_id >= 5 limit 100;

7、oracle 分页sql

## 把查询的sql  放中间一套就好了  select * from eb_item
select * from(
        select rownum rw,a.* from (
             
             ## 查询sql 区
                select * from eb_item t
                where t.brand_id = 1003
                and t.audit_status = 1
                and t.show_status = 1
                and t.item_name like '%星%'
             ## 查询sql 区

          ) a where rownum < 11
 ) b where b.rw > 1

二、增删改查sql

select * from ws_user
select * from ws_order

1、添加数据

 ## 语法 : INSERT  INTO表名[(列名1,列名2,...)]VALUES(值1,值2,...)
 ##   或 : INSERT  INTO 表名VALUES(值1,值2,...)
insert into ws_user(user_id,username,password) values(10,"zhangsan",'123456');

1、id自增主键为 null 就好了

insert into ws_user(user_id,username,password) values(null,"zhangsan",'123456');

2、时间类型(now(),当前时间)

insert into ws_order(order_id,start_time) values(999,now());

3、指定时间

insert into ws_order(order_id,start_time) values(1001,'1996-3-2 16:00:00');
insert into ws_order(order_id,start_time) values(1001,'1996/3/2 16:00:00');

4、插入二进制文件,指定文件路径即可(这里表里的字段刚添加的,原没有该字段)

insert into ws_file(file_id,fileMp3) values(1001,'C:\Users\Administrator\Music\虾米音乐\黄嘉雯-情一动心就痛.mp3');

2、修改数据

## 全部修改语法:UPDATE 表名 SET 列名1=值1,列名2=值2,....(且勿随意使用)
## 指定修改语法:UPDATE 表名 SET 列名1=值1,列名2=值2,....WHERE 修改条件;

update ws_user set username = "李四",password="123456" where user_id = 10;

3、删除数据

# 语法 : DELETE FROM 表名	WHERE	删除条件;

delete from ws_user where user_id = 10;

事务,我们打开另外一个窗口,发现上面的操作并没有生效
数据库变更会发生锁的情况(此处应用可以解决项目多线程并发带来的数据安全问题)
当两个数据库的连接同时来修改同一数据时,一定会有一连接先修改,另一个连接就会等待直到第一个连接修改完毕再修改

如需提交:

commit;

如需回滚:

rollback;

三、表的操作、创建/修改/删除

1、创建表

# 语法:ALTER TABLE 表名称 (列名1 类型 [DEFAULT 默认值],列名1 类型 [DEFAULT 默认值]...)
# 如果你不想字段为 NULL 可以设置字段的属性为 NOT NULL, 在操作数据库时如果输入该字段的数据为NULL ,就会报错。
# AUTO_INCREMENT 定义列为自增的属性,一般用于主键,数值会自动加1。
# PRIMARY KEY关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔。
# ENGINE 设置存储引擎,CHARSET 设置编码。

CREATE TABLE runoob_tbl(
   runoob_id INT NOT NULL AUTO_INCREMENT, # NOT NULL:不为空,AUTO_INCREMENT:自增
   runoob_title VARCHAR(100) NOT NULL,
   runoob_author VARCHAR(40) NOT NULL,
   submission_date DATE,
   PRIMARY KEY ( runoob_id )             # PRIMARY KEY :定义主键列
 )ENGINE=InnoDB DEFAULT CHARSET=utf8;    # ENGINE :设置存储引擎,CHARSET:设置编码。

2、修改表

alter table runoob_tbl rename runoob_tb2;              # 修改表名
alter table runoob_tb2 add column name varchar(10);    # 添加表列
alter table runoob_tb2 modify name char(20)            # 修改表列类型
alter table runoob_tb2 change name username char(40)   # 修改表列类型+表列名
alter table runoob_tb2 drop  column name;              # 删除表列
alter table runoob_tb2 change column username username1 varchar(30)  #修改表列名

3、删除表

# 语法:DROP TABLE 表名
DROP TABLE runoob_tb2;

4、清空表数据(直接清空,无法回滚)

truncate table runoob_tb2;

5、表的约束

# 主键约束:PRIMARY KEY ,主键是唯一的,不可重复
# 非空约束:NOT NULL ,表示该字段不能为空
# 唯一约束:UNIQUE,表示该字段字段值不能重复
# 检查约束:CHECK(GENDER IN(1,2)),表示该字段只能填写 1或2
# 外键约束:constraint 


CREATE TABLE runoob_tbl(
   runoob_id INT NOT NULL AUTO_INCREMENT, 
   runoob_title VARCHAR(100) NOT NULL UNIQUE,
   runoob_author VARCHAR(40) NOT NULL,
	 runoob_type INT CHECK(GENDER IN(1,2)),
   submission_date DATE,
   PRIMARY KEY ( runoob_id )
	 # constraint 外键_pk primary key(order_id)
 )ENGINE=InnoDB DEFAULT CHARSET=utf8;    

四、序列

oracle使用 mysql不需要

1、创建序列

CREATE SEQUENCE seqpersonid;

2、NextVal :取得序列的下一个内容

select seqpersonid.nextval from dual;#####   3、CurrVal :取得序列的当前内容

select seqpersonid.currval from dual;

3、自增sql,

oracle自增列使用 seqpersonid.nextval,mysql 输入null 就好了

insert into ws_user(user_id,username,password) values(seqpersonid.nextval,"zhangsan",'123456');

五、索引

什么情况下所有索引?
1、数据量大,查询慢的表
2、经常查询的字段,where条件中经常使用
优点:
1、索引的作用:通过索引查找记录至少要比顺序扫描记录大致快100倍
2、索引实现原理:生成二叉数索引文件,通过二叉数,B+树,折半查找
3、数据量越大,索引查询提升的效率越高
缺点:
1、占用磁盘空间
2、影响增删改ddl效率

mysql --- sql 语句大全 || 索引 || 储存函数+过程+触发器+视图_第1张图片
如图:
不使用索引:按左边图顺序查询,效率低
使用索引后:根据查询数据的大小判断,比如查9,小于六的直接不考虑,直接查询大于6的,在往下找,如图查找2次就找到9了,顺序查询则需要查9次

explain 关键字

explain 关键字,放在查询前面可以通过type查看查询是否使用了索引

1、普通索引 (不常用)

# 创建索引一语法:CREATE index 索引名  on 表名(列名((length)))
CREATE INDEX uname1 ON ws_user(username);

# 创建索引二语法:CREATE index 表名 ADD INDEX 索引名(列名)
ALTER TABLE ws_user ADD INDEX uname(`username`);

2、主键索引

# 语法: alter table 表名 add primary key (列名);
alter table articles drop primary key;

3、唯一索引

1、索引列不能有重复数据,必须唯一约束字段, 唯一约束可以为null
2、CHAR,VARCHAR类型,length可以小于字段的实际长度
3、BLOB,TEXT类型就必须指定长度

    # 语法:CREATE UNIQUE INDEX IndexName ON `TableName`(`字段名`(length)); 
    CREATE UNIQUE INDEX nam ON ws_user(`username`(10)); 

4、全文索引 (不用,一般用搜索引擎,如es,solr)

说明:
1.在mysql中fulltext 索引只针对 myisam生效
2.mysql自己提供的fulltext针对英文生效->sphinx (coreseek) 技术处理中文
3.使用方法是 match(字段名…) against(‘关键字’)
4.全文索引:停止词, 因为在一个文本中创建索引是一个无穷大的数,因此,对一些常用词和字符,就不会创建这些词,称为停止词.比如(a,b,mysql,the)

创建全文索引

CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT,
       FULLTEXT (title,body)    -- 添加全文索引
     )engine=myisam charset utf8;

查询每行和database的匹配度

 select match(title,body) against ('database') from articles;

查询

# 错误用法:
select * from articles where body like '%mysql%'; 错误用法 索引不会生效
# 正确用法
select * from articles where match(title,body) against ( 'database')

5、组合索引

1、不按索引最左列开始查询(多列索引)
2、查询中某个列有范围查询,则其右边的所有列都无法使用查询(多列查询)
3、不能跳过某个字段来进行查询,这样利用不到索引

#  语法: CREATE INDEX 索引名 On `表名`(`字段名`(字段长度),`password`(10),....);
CREATE INDEX up On `ws_user`(`username`(10),`password`(10));

6、查询表的索引

desc  表名;   不能显示索引名称
show index from 表名
show keys from 表名

在这里插入图片描述

7、删除表索引

DROP INDEX up ON `ws_user`;

8、查询所用使用率

show status like ‘handler_read%’;

大家可以注意:
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。
handler_read_rnd_next:这个值越高,说明查询低效。

六、视图

创建视图:	CREATE VIEW 视图名(列1,列2...) AS SELECT (列1,列2...) FROM ...;
使用视图:	当成表使用就好
修改视图:	CREATE OR REPLACE VIEW 视图名 AS SELECT [...] FROM [...];
查看数据库已有视图:	SHOW TABLES [like...];(可以使用模糊查找)
查看视图详情:	DESC 视图名 或 SHOW FIELDS FROM 视图名
视图条件限制:	[WITH CHECK OPTION]

创建视图

创建视图1,vuser

create view vuser as select * from ws_user u;

创建视图2,vuser,视图名存在会覆盖

create or replace view vuser AS select * from ws_user u;

创建视图3,vuser ,视图名存在覆盖,且视图数据不可修改

create or replace view vuser AS select * from ws_user with check option;

查询/插入/修改 视图数据

select * from vuser;

– 视图插入数据(同sql操作,需有视图数据可改权限)

insert into vuser(user_id,username,password) values(9880,'柴油','35');

– 视图修改数据(同sql操作,需有视图数据可改权限)

update vuser set username = '66666',password = '1232131' where user_id= 9878;

– 查看视图详情

DESC vuser; 
或
SHOW FIELDS FROM vuser;

– 查看已有视图(视图 = 临时表)

SHOW TABLES;

七、临时表与复制表

临时表

创建临时表,断开连接释放 (系统自动删除)

create TEMPORARY table Test(
    regName varchar(20),
		mobilePhone char(11)
);

查询

select * from Test;

删除临时表

drop table Test;

查询所有表

show tables;

复制表

复制的是建表sql,直接在次复制字段内容

show create table ws_user;

复制结构,直接出来一个新的ws_user1 表(无数据)

create table ws_user1 like ws_user;

复制结构和数据(会丢掉一些特性,比如主键自增等)

create table ws_user2 as select * from ws_user;

复制+临时表( 密码等于123456的全部复制到临时表数据中)

create TEMPORARY table leave_user as select * from ws_user u where u.password = '123456';

查询临时表

select * from leave_user;

八、if,case及判空表达式

if / case

if,第一个参数为判断表达式,true返回第二个参数,false返回第三个参数

select username,password,if(password='123456','yes','no') from ws_user

#case 判断,满足条件进入, 可以定义多个判断条件,断条件可以and连接 whene password = ‘123456’ and____ then ‘yes’ ,

select username,password,case when password = '123456' then 'yes' else 'no' end from ws_user

案例一

select case 2
when 1 then 'one'
when 2 then 'two'
else 'more'
end;

案例二

select case 
when 1 > 2 then 'false' 
when 1 < 2 then 'true'
else 'error'
end;

判空

– 获取空字段数据

select * from ws_user where password is null;

– 判空,空返回第二个值,不为空返回第一个参数的值

select password,ifnull(password,"空值") from ws_user  where password is null;

九、储存函数

说明:储存函数调用为 select + 函数名

基础部分–系统函数/删除函数

此为修改分饰符 ;为 //,防止函数中的sql 出现 ; 结束报错

delimiter ;

系统函数 avg,concat等

   # 平均值
    -- select avg(leaveAmount) FROM member;
    -- select CONCAT('hello','-','lemon')
    # 字符串拼接
    select CONCAT(username,'-',password) from ws_user;

删除函数,return Hello World!

DROP FUNCTION IF EXISTS f_say_hello;

如果创建函数1418错误运行以下sql

show variables like 'log_bin_trust_function_creators';
set global log_bin_trust_function_creators=1;
show variables like 'log_bin_trust_function_creators';

自定义函数

自定义函数语法/ 调用方法

delimiter //                                # 把结束分号改为 //
DROP FUNCTION IF EXISTS f_is_tuhao;         # 删除原有函数
CREATE FUNCTION f_is_tuhao(memberId INT)    # 创建函数 函数名(传入值 值数据类型)
RETURNS VARCHAR(20)                         # 返回值类型
BEGIN                                       # 程序体开始

	 RETURN _msg;                           # 返回值
END//                                       # 程序体结束
delimiter;                                  # 把结束还原为 ;

调用方法

select 函数名 

创建自定义函数,return Hello World!

该函数返回 Hello World!

delimiter //
CREATE FUNCTION f_say_hello()    # 函数名
RETURNS VARCHAR(20)              # 返回的数据类型
BEGIN 
	-- 多条sql。。。。             # 函数体,也就是sql
	RETURN 'Hello World!';         # return 返回值
END
//
delimiter ;


-- 调用函数
select f_say_hello();

创建自定义带参数的函数,return 传入的值

delimiter //
DROP FUNCTION IF EXISTS f_say_a_word;  # 删除
CREATE FUNCTION f_say_a_word(word VARCHAR(20))
RETURNS VARCHAR(20)
BEGIN 
	RETURN word;
END//
delimiter ;


-- 调用函数
select f_say_a_word('Hello World!!!');

创建自定义带参数的函数,return a+b(1+2)

delimiter //
DROP FUNCTION IF EXISTS f_add_num;
CREATE FUNCTION f_add_num(a INT,b INT)
RETURNS INT
BEGIN 
	RETURN a+b;
END
//
delimiter ;


-- 调用函数
select f_add_num(1,2);

创建自定义函数,return 平均消费(avg)

-- 得到某个会员的平均的消费额
delimiter //
# 删除存在
DROP FUNCTION IF EXISTS f_get_avg_amount;
# 创建
CREATE FUNCTION f_get_avg_amount(userId INT)
RETURNS DECIMAL(18,2)
BEGIN 
	-- 定义一个变量:保存该用户的消费总额
	DECLARE _sumAmount DECIMAL(18,2) DEFAULT 0.00;
	-- 定义一个变量:保存该用户的消费次数
	DECLARE _investTimes INT DEFAULT 0;

	-- 为变量赋值
-- 	SET _sumAmount=100.00;

	-- 查询该用户的消费总额 (自定义查询sql) INTO _sumAmount 为赋值
	SELECT SUM(amount)   FROM invest WHERE memberId=userId;
	
	-- 查询该用户的消费次数 (自定义查询sql)
	SELECT COUNT(1) INTO _investTimes FROM invest WHERE memberId=userId;

	-- IFNULL 为空判断,出现除0为空
	RETURN IFNULL(_sumAmount/_investTimes,0.00);
END//
delimiter ;

函数判断

IF 分支判断函数

– 传入一个memberId,返回会员是否是土豪(>40000)、无产(<10000)、中产(>=10000 and <40000)

delimiter //
DROP FUNCTION IF EXISTS f_is_tuhao;         # 删除原有函数
CREATE FUNCTION f_is_tuhao(memberId INT)    # 创建函数 函数名(传入值 值数据类型)
RETURNS VARCHAR(20)                         # 返回值类型
BEGIN                                       # 程序体开始
	
	DECLARE _msg VARCHAR(20);                 # 定义msg保存输出信息
	DECLARE _amount DECIMAL(18,2);	          # 定义一个局部变量保存查询出来的该会员的余额
	
	# 查询余额并赋值给变量 INTO (sql 数据库查询)
	SELECT leaveAmount INTO  _amount FROM member WHERE id=memberId;   _amount

	if _amount<10000 THEN                    # if分支判断变量值的大小
		  set _msg = '我是无产阶级';
	elseif _amount>=10000 AND _amount<40000 THEN
		  set _msg = '我是中产阶级';
	else
		  set _msg = '我是土豪';
	end if;                                  # if分支判断结束标识

	RETURN _msg;
END//                                       # 程序体结束标识
delimiter;

CASE 判断列子1 (匹配)

– 创建一个函数,传入一个memberId,返回用户的类型(1:普通 2:内部 其他)

delimiter //
DROP FUNCTION IF EXISTS f_get_member_type_msg;        # 删除原有函数
CREATE FUNCTION f_get_member_type_msg(memberId INT)   # 创建函数 函数名(传入值 值数据类型)
RETURNS VARCHAR(20)                                   # 返回值类型
BEGIN                                                 #  程序体开始
	DECLARE _msg VARCHAR(20);                           # 定义retuen 变量
	DECLARE _type TINYINT;                              # 定义类型变量

	SELECT type INTO _type FROM member WHERE id=memberId; # 查询sql并把结果赋值变量(值为 1或2或其他)

	CASE _type                  	    #  判断开始
	WHEN 1 THEN SET _msg='普通用户';     #  type = 1 执行 set
	WHEN 2 THEN SET _msg='内部用户';     #  type = 2 执行 set
	ELSE SET _msg='其他用户';            #  type 不等于1和2 执行 set
	END CASE; -- !!!!!                   #  判断结束

	RETURN _msg;                         #  返回值
END//                                  #  程序体结束
delimiter;

CASE 判断列子2 ( >= <=)

– 传入一个memberId,返回会员是否是土豪(>=40000)、无产(<10000)、中产(>=10000 and <40000)

delimiter //
DROP FUNCTION IF EXISTS f_is_tuhao_case;
CREATE FUNCTION f_is_tuhao_case(memberId INT)
RETURNS VARCHAR(20)
BEGIN
	DECLARE _msg VARCHAR(20);	      -- 定义_msg保存输出信息
	DECLARE _amount DECIMAL(18,2);	  -- 定义一个局部变量保存查询出来的该会员的余额
	SELECT leaveAmount INTO  _amount FROM member WHERE id=memberId;  -- 查询出来的该会员的余额,保存到局部变量_amount中
	
	 -- case的条件判断、分支控制
	CASE	
	WHEN _amount >= 40000 THEN SET _msg='我是土豪';
	WHEN _amount >= 10000 AND _amount<40000 THEN SET _msg='我是中产';
	ELSE SET _msg = '我是无产阶级';
	END CASE;

	RETURN _msg;
END//
delimiter;

函数循环

LOOP循环 ,需手动加入结束循环标识

– 向表中循环插入一百条数据

delimiter //
DROP FUNCTION IF EXISTS f_is_tuhao;         # 删除原有函数
CREATE FUNCTION f_is_tuhao(memberId INT)    # 创建函数 函数名(传入值 值数据类型)
RETURNS VARCHAR(20)                         # 返回值类型
BEGIN                                       # 程序体开始

DECLARE _num INT;                         # 创建变量
SET _num=1;                               # 初始化变量
insert_loop:LOOP                          # 循环开始 (定义循环名:LOOP)

	## 循环体
	INSERT INTO tb_lemon_grade(s_name,score,c_name) VALUES('Tom',80,'30期'); 
	SET _num=_num+1;                       # 迭代语句,每循环一次_num +1,
	
	IF _num%2=0                            # 判断逻辑-偶数执行下两行代码
		THEN ITERATE insert_loop;          # 跳出本次循环
	END IF;                                # 判断结束标识
	
	IF _num>100                            # 判断逻辑(是否执行if内代码跳出循环)
		THEN LEAVE insert_loop;            # 跳出整个循环
	END IF;                                # 判断结束标识
	
 END LOOP insert_loop;                   # 循环结束标识
 RETURN '1';                             # 返回值
END//                                    # 程序体结束标识
delimiter;

REPEAT循环 ,自带跳出循环

-- 向表中循环插入一百条数据

delimiter //
DROP FUNCTION IF EXISTS f_loop_insert_3;   # 删除原有函数
CREATE FUNCTION f_loop_insert_3()          # 创建函数 函数名(传入值 值数据
RETURNS VARCHAR(20)                        # 返回值类型
BEGIN                                      # 程序体开始

	DECLARE _num INT;                        # 创建变量                              
	SET _num=0;                              # 初始化变量
		
	insert_repeat:REPEAT                     # 循环开始 (定义循环名:REPEAT)
		SET _num=_num+1;                     # 迭代语句,每循环一次_num +1,
			
		## 循环体
		INSERT INTO tb_lemon_grade(s_name,score,c_name) VALUES(CONCAT('Tom_',_num),80,CONCAT(_num,'期'));
	UNTIL _num=100 END REPEAT insert_repeat;    #  _num=100 跳出整个循环

	RETURN "1";                              # 返回值
END
//
delimiter;

WHILE 循环

– 向表中循环插入一百条数据

delimiter //
DROP FUNCTION IF EXISTS f_loop_insert_4; # 删除原有函
CREATE FUNCTION f_loop_insert_4()        # 创建函数 函
RETURNS VARCHAR(20)                      # 返回值类型
BEGIN                                    # 程序体开始

	DECLARE _num INT;                      # 创建变量  
	SET _num=1;                            # 初始化变量 
	insert_while:WHILE _num<=100 DO        # 循环开始 (定义循环名:WHILE 循环条件) 
		## 循环体
		INSERT INTO tb_lemon_grade(s_name,score,c_name) VALUES(CONCAT('Tom_',_num),80,CONCAT(_num,'期'));
		
		SET _num=_num+1;                     # 迭代语句,每循环一次_num +1,
	    END WHILE insert_while;              # 满足while条件跳出循环

	RETURN "1";                              # 返回值
END//
delimiter;

十、储存过程

注意:
1、储存过程中可以调用储存函数,
2、储存函数中不可以调用储存过程
3、储存过程可以传值,储存函数不可以

#调用储存过程语法: Call 储存过程名

– 创建存储过程
语法:CREATE PROCEDURE 过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 …] 过程体
如:

 DELIMITER //
    CREATE PROCEDURE Test(OUT s int)
    BEGIN
      SELECT COUNT(*) FROM ws_user;
    END
 // 
DELIMITER ;

DELIMITER ;”的意为把分隔符还原
IN:参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值 OUT:该值可在存储过程内部被改变,并可返回
INOUT:调用时指定,并且可被改变和返回
BEGIN与END 中间表示的是过程体

in 列子(只能传值进去,不返回值)

DELIMITER //
  CREATE PROCEDURE in_param(out p_in int)
    BEGIN
     select p_in;
     set p_in=2;
     select p_in;
    END;
    //
DELIMITER ;

set @p_in=1;            # 设置值
Call in_param(@p_in);   # 调用储存过程,in过程值可更改数据
select @p_in;           # 查询结果,还是1

out 列子

#存储过程OUT参数
DELIMITER //
  CREATE PROCEDURE out_param(OUT p_out int)
    BEGIN
      SELECT p_out;
      SET p_out=2;
      SELECT p_out;
    END;
    //
DELIMITER ;

#调用
SET @p_out=1;           # 设置值
CALL out_param(@p_out); # 调用储存过程,out 改变的值返回(原数据置空)
SELECT @p_out;          # 查询结果,变成2了

inout 列子

#存储过程INOUT参数
DELIMITER //
  CREATE PROCEDURE inout_param(INOUT p_inout int)
    BEGIN
      SELECT p_inout;
      SET p_inout=2;
      SELECT p_inout;
    END;
    //
DELIMITER ;
#调用
SET @p_inout=1;              # 设置值
CALL inout_param(@p_inout) ; # 调用储存过程,inout 改变的值返回
SELECT @p_inout;             # 查询结果,变成2了

in out inout 的比较 =============================

delimiter //
DROP PROCEDURE if EXISTS proc_in_out_inout;
CREATE PROCEDURE proc_in_out_inout(
	IN in_num INT UNSIGNED,
	OUT out_num INT UNSIGNED,
	INOUT inout_num INT UNSIGNED
)
BEGIN
	
	SET in_num=100;                  # 值该变了不会返回
	SET out_num=out_num+1;           # 返回null,赋值具体的值可返回
	SET inout_num=inout_num+in_num;  # 返回改变后的值

END
//
delimiter ;


## 定义及查询
set @a =1;
set @b =10;
set @c =100;
CALL proc_in_out_inout(@a,@b,@c);
select @a,@b,@c;  

变量

set @name = 'wangsong';  # 定义变量
select @name;            # 查询变量

set @num = 1+2+3;
select @num; 

在存储过程中使用用户变量 CONCAT 字符串拼接方法

CREATE PROCEDURE GreetWorld() SELECT CONCAT(@greeting,' World');
SET @greeting='Hello';


CALL GreetWorld();

在存储过程间传递全局范围的用户变量

CREATE PROCEDURE p1() SET @last_proc='p1';
CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_proc);
CALL p1();
CALL p2();

查询存在的所有存储过程

#SELECT name FROM mysql.proc WHERE db='jpa';
SELECT routine_name FROM information_schema.routines WHERE routine_schema='jpa';
SHOW PROCEDURE STATUS WHERE db='jpa';

查看存储过程详细信息

SHOW CREATE PROCEDURE jpa.p2;

修改储存过程

ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
characteristic:
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'

sp_name 参数表示存储过程或函数的名称;
characteristic 参数指定存储函数的特性。
CONTAINS SQL 表示子程序包含SQL语句,但不包含读或写数据的语句;
NO SQL 表示子程序中不包含SQL语句;
READS SQL DATA 表示子程序中包含读数据的语句;
MODIFIES SQL DATA 表示子程序中包含写数据的语句。
SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行,DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。
COMMENT 'string’是注释信息。

将读写权限改为MODIFIES SQL DATA,并指明调用者可以执行。

ALTER  PROCEDURE  num_from_employee
  MODIFIES SQL DATA
  SQL SECURITY INVOKER ;

将读写权限改为READS SQL DATA,并加上注释信息’FIND NAME’。

ALTER  PROCEDURE  name_from_employee
  READS SQL DATA
  COMMENT 'FIND NAME' ;

删除储存过程 =================

DROP PROCEDURE [过程1[,过程2…]]

变量作用域

内部变量在其作用域范围内享有更高的优先权,当执行到end时,内部变量消失,不再可见了,在存储
过程外再也找不到这个内部变量,但是可以通过out参数或者将其值指派给会话变量来保存其值。

DELIMITER //
  CREATE PROCEDURE proc()
    BEGIN         # 储存体
      DECLARE x1 VARCHAR(5) DEFAULT 'outer';
        BEGIN     # 内储存体
          DECLARE x1 VARCHAR(5) DEFAULT 'inner';
          SELECT x1;
        END;
      SELECT x1;
    END;
    //
DELIMITER ;


#调用
CALL proc();

条件语句 IF-THEN-ELSE

#条件语句IF-THEN-ELSE
DROP PROCEDURE IF EXISTS proc3;

DELIMITER //
CREATE PROCEDURE proc3(IN parameter int)   # 创建储存过程
  BEGIN                                    # 储存过程开始
  
    DECLARE var int;                       # 定义变量
    SET var=parameter+1;                   # 定义变量
    
    IF var=0 THEN                          # var=0  执行
      INSERT INTO t VALUES (17);
    END IF ;
    
    IF parameter=0 THEN                    # parameter=0 执行
      UPDATE t SET s1=s1+1;
    ELSE                                   # parameter 不等于 0 执行
      UPDATE t SET s1=s1+2;
    END IF ;
    
  END ;
  //
DELIMITER ;

储存过程定义异常

定义异常
    delimiter //
    DROP PROCEDURE IF EXISTS p_condition_handler;
    CREATE PROCEDURE p_condition_handler()
    BEGIN
    #一:定义异常
    -- 1:sqlstate_value
    -- 	DECLARE does_not_exist CONDITION FOR SQLSTATE '42S02';
    
    -- 	2:mysql_error_code
       DECLARE does_not_exist CONDITION FOR 1146;
	 
	 SELECT * FROM hello;
	 # 查询异常不在执行下列sql
	 INSERT INTO member(id) VALUES(10090);
END//
delimiter;

储存过程处理异常

    delimiter //
    DROP PROCEDURE IF EXISTS p_condition_handler;
    CREATE PROCEDURE p_condition_handler()
    BEGIN

    # 遇到SQLSTATE '42S02' 错误程序继续下走,并给变量flag赋值为1
    -- 	DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @=1;

  
    # 遇到 1146 错误程序继续下走,并给变量flag赋值为1
    -- 	DECLARE CONTINUE HANDLER FOR 1146 SET @flag=1;

    # 遇到自定义异常 错误程序继续下走,并给变量flag赋值为1
    -- 	DECLARE CONTINUE HANDLER FOR does_not_exist SET @flag=1;
	
    DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @flag=1;

	SET @flag=2;
	# 查询出了异常,还希望执行 insert 语句,可定义相应的异常
	SELECT * FROM hello;
	INSERT INTO member(id) VALUES(10090);
END//
delimiter;


-- ERROR 1146 (42S02): Table 'lemon.hello' doesn't exist
-- 1:已经发生了错误
-- 2: 1146:错误码
-- 3:42S02:sql状态值

十一、触发器 (=监听器)

当向 ws_user表中插入一行记录时,触发储存过程直接向 ws_user2 表插入一条记录

delimiter //
DROP TRIGGER IF EXISTS t_insert_invest;         # 删除储存过程
CREATE TRIGGER t_insert_invest AFTER INSERT     # 创建储存过程 + INSERT触发(插入数据触发)
ON ws_user FOR EACH ROW                         # on 表名(触发器关联的表)
BEGIN
  ## 过程体
  INSERT INTO ws_user2(password,username) VALUES('123456','wangwu');
END//
delimiter ;


# 当向 ws_user表中插入一行记录时,触发 t_insert_invest 储存过程
INSERT INTO ws_user(password,username) VALUES('123456','wangwu3')


   # 查询
    select count(*) from ws_user;
    select count(*) from ws_user2;
    select * from ws_user;
    select * from ws_user2;

– 创建一个触发器,再删除一个投资用户时,删除其相关的信息:投资、回款计划信息、用户信息

OLD.id 的说明
old :删除触发时之前的老数据(表对象)
new :新增触发时添加的新数据(表对象)

delimiter //
CREATE TRIGGER t_delete_member_info BEFORE DELETE 
ON member FOR EACH ROW
BEGIN
	-- 删除所有的回款计划信息
	DELETE FROM repayment WHERE investId in(select id from invest where memberId=OLD.id);

	-- 删除投资记录
	delete from invest where memberId = OLD.id;
END//
delimiter;

十二、事件(定时任务)

1、使用事件需开启定时器
2、定义事件,使用sql 还是储存过程看业务需求
下方有的使用过程,有的使用sql

SHOW VARIABLES LIKE 'event_scheduler';  # 查看是否开启定时器(事件)
SET GLOBAL event_scheduler = 1;         # 开启定时器 0:off 1:on


-- 开启事件,event_test为事件名
ALTER EVENT event_insert_member ON 
COMPLETION PRESERVE ENABLE; 

-- 关闭事件,event_test为事件名
ALTER EVENT event_insert_member ON 
COMPLETION PRESERVE DISABLE;

定义事件

每隔一秒自动调用 e_test()存储过程

CREATE EVENT IF NOT EXISTS event_test
ON SCHEDULE EVERY 1 SECOND
ON COMPLETION PRESERVE 
DO CALL e_test();         

每隔一分钟,执行一次语句

delimiter //
CREATE EVENT event_insert_member    # 定义:CREATE EVENT 函数名
ON SCHEDULE EVERY 1 MINUTE          # ON SCHEDULE 定义时间
ON COMPLETION PRESERVE ENABLE DO
BEGIN
    # 执行语句
	  INSERT INTO ws_user2(password,username) VALUES('123456','wangwu');
END//
delimiter ;

每天凌晨一点执行 INSERT sql语句

delimiter //
CREATE EVENT IF NOT EXISTS temp_event   
ON SCHEDULE EVERY 1 DAY STARTS DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL 1 HOUR)   
ON COMPLETION PRESERVE ENABLE   
DO INSERT INTO ws_user2(password,username) VALUES('123456','wangwu');
//
delimiter ;

每天0点05分从数据表中清除字段(yhendtime)小于当前时间戳的记录:

delimiter //
CREATE EVENT dele_from_thinkyh
ON SCHEDULE EVERY 1 DAY STARTS '2016-12-30 00:05:00' 
ON COMPLETION PRESERVE ENABLE COMMENT '每天清除数据表think_youhui中的过期的记录' 
DO DELETE FROM think_youhui WHERE think_youhui.yhendtime

从现在开始每隔九天定时执行

delimiter //
CREATE EVENT EVENT1 
ON SCHEDULE EVERY 9 DAY STARTS NOW() 
ON COMPLETION PRESERVE ENABLE 
DO 
BEGIN 
   INSERT INTO ws_user2(password,username) VALUES('123456','wangwu');
END 
//
delimiter ;

每个月的一号凌晨1 点执行

delimiter //
CREATE EVENT EVENT2 

ON SCHEDULE EVERY 1 MONTH STARTS DATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTERVAL DAY(CURDATE())-1 DAY), INTERVAL 1 MONTH),INTERVAL 1 HOUR) 
ON COMPLETION PRESERVE ENABLE 
DO 
BEGIN 
   INSERT INTO ws_user2(password,username) VALUES('123456','wangwu');
END 
//
delimiter ;

每个季度一号的凌晨2点执行

delimiter //
CREATE EVENT TOTAL_SEASON_EVENT 
ON SCHEDULE EVERY 1 QUARTER STARTS DATE_ADD(DATE_ADD(DATE( CONCAT(YEAR(CURDATE()),'-',ELT(QUARTER(CURDATE()),1,4,7,10),'-',1)),INTERVAL 1 QUARTER),INTERVAL 2 HOUR) 
ON COMPLETION PRESERVE ENABLE 
DO 
BEGIN 
   # CALL SEASON_STAT(); 可以调用储存过程
   INSERT INTO ws_user2(password,username) VALUES('123456','wangwu');
END 
//
delimiter ;

每年1月1号凌晨四点执行

delimiter //
CREATE EVENT TOTAL_YEAR_EVENT 
ON SCHEDULE EVERY 1 YEAR STARTS DATE_ADD(DATE(CONCAT(YEAR(CURDATE()) + 1,'-',1,'-',1)),INTERVAL 4 HOUR) 
ON COMPLETION PRESERVE ENABLE 
DO 
BEGIN 
  # CALL YEAR_STAT(); 可以调用储存过程
  INSERT INTO ws_user2(password,username) VALUES('123456','wangwu');
END
//
delimiter ;

你可能感兴趣的:(Mysql的,sql,语句大全,储存函数+过程+触发器+视图)