回顾
联合查询:union,多表合并和单表不同查询条件
联合查询使用order by:select语句必须使用括号,还必须配合limit
子查询:查询语句中有查询语句
分类:按位置(from、where、exists),按返回结果:标量,列,行和表
视图:
节省SQL语句;安全性控制
本质:虚拟表,有结构无数据
数据操作:多表只能改,单表可以增删改(增删有条件限制)
算法:undefined未定义,temptable临时表和merge合并
文件备份与还原
文件备份:存储引擎(myisam适用)
单表数据备份:只能备份数据
SQL备份:备份的是SQL指令(mysqldump.exe客户端备份)
增量备份:备份系统日志文件
事务安全
免费的存储引擎中只有innodb是支持事务的,其他的并不支持。
1、事务原理
原理:事务开启之后,所有的操作都会临时保存到事务日志,事务日志只有在得到commit命令才会同步到数据表,其他任何情况都会清空(rollback,断电,断开连接)
2、回滚点
在某个成功的操作完成之后,后续的操作有可能成功有可能失败,但是不管成功还是失败,前面操作都已经成功,可以在当前成功的位置,放置一个点,可以供后续失败操作返回到该位置,而不是返回所有操作,这个点称之为回滚点。
设置回滚点语法:savepoint 回滚点名字;
回到回滚点语法:rollback to 回滚点名字;
3、自动事务
自动事务:系统通过autocommit变量控制
show variables like 'autocomment';
--关闭自动提交
set autocommit = off/0;
4、事务的四大特性
A:Atomic 原子性,事务的整个操作是一个整体,不可分割,要么全部成功,要么全部失败
C:Consistency一致性,事务操作的前后,数据表中的数据没有变化
I:Isolation隔离性,事务操作是相互隔离不受影响
D:Durability持久性,数据一旦提交,不可改变,永久的改变数据表数据
5、事务的隔离级别:
5.1、未提交读(脏读)
当一个A用户,读到了B用户未提交的数据。比如,B账户减了100,但是没有提交事务,A用户查询B用户时,会发现减了100,如果事务不提交,回滚,再次查询是没有减少的。
5.2、提交读(不可重复读,大多数数据库默认的,但不是mysql数据库的)
一个事务范围内多次查询却返回不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
5.3、脏读和不可重复读的区别:
脏读:某一事务读取了另一事务未提交的脏数据。
不可重复读:读取了前一事务提交的事务,可能结果不同
虚读:事务1是读取某一数据后,事务2对其进行了修改,当事务1再次读取的时候,得到与前一次不同的值
幻读:事务在操作过程中进行两次查询,第二次查询的结果比第一次查询多了或少了几条数据
5.4、可重复读(mysql默认的)
多次读取到的数据是一致的结果,可重复读可能会导致幻读。
幻读,简单的说就是当用户读取某一范围的数据时,另一个事务又在该范围插入了新行,当用户再次读取时,会发现新的“幻影”行
5.5、可串行化
最高级别的隔离,强制事务进行排序,使之不会冲突,从而解决了幻读问题。在每个读的数据行加上读锁,可能导致大量的超时和锁消耗
锁机制:innodb默认是行锁,但是如果在事务操作的过程中,没有使用到索引,那么系统会自动全表检索数据,自动升级为表锁。
行锁:只有当前行被锁住,别的用户不能操作
表锁:整张表被锁住,别的用户都不能操作
Mysql数据库的自动提交
--mysql默认是自动提交
select @@autocommit;
--修改为手动提交
set autocommit = 0;
表锁定
--这个表所有人都只能读取,不能写操作
lock table 表名 read;
--解锁所有表
unlock tables;
--写锁定,这个表自己这个线程可以写和读,但是别的线程只能写操作。
lock table 表名 write;
事务的操作是针对数据的操作,不是针对结构的操作。如果删除了一个表,然后回滚,表还是会被删除的。
变量(系统变量)
--查看所有系统变量
show variables;
--查看系统变量值
select @@version,@@autocommit,@@auto_increment_offset;
--修改会话级别变量
set autocommit = 0;
修改系统变量分为两种方式:会话级别和全局级别
会话级别:临时修改,当前客户端当次连接有效
set 变量名 = 值;set @@变量名 = 值;
全局级别:一次修改,永久生效(对所有客户端都生效)
set global 变量名 = 值;
如果客户端当前已经连上服务器,那么当次修改无效,要退出重新登录才会生效。
变量(自定义变量)
1、定义变量
系统为了区分系统变量,规定用户自定义变量必须使用一个@符号
set @变量名 = 值;
自定义变量也是类似系统变量查看
select @变量名
在MySQL中,"="会默认的当做比较符号处理(很多地方),MySQL为了区分比较和赋值的概念,重新定义了一个新的赋值符号“:=
方案1:边赋值,边查看结果
select @变量名 :=字段名 from 数据源;
--从字段中取值赋值给变量名,如果使用=会变成比较
触发器
触发器:trigger,事先为某张表绑定好一段代码,当表中的某些内容发生改变的时候(增删改),系统会自动触发代码执行。
触发器:事件类型、触发事件、触发对象
事件类型:增删改,三种类型 insert,delete和update
触发时间:前后:before和after
触发对象:表中的每一条记录(行)
一张表中只能拥有一种触发时间的一种类型的触发器,最多一张表能有6个触发器。
1、创建触发器
触发器基本语法
--临时修改语句结束符
delimiter --自定义符号:后续代码中只有碰到自定义符号才算结束
create trigger 触发器名字 触发器时间 事件类型 on 表名 for each row
begin --代表左大括号,开始
--里面就是触发器的内容,每行内容都必须使用语句结束符:分号
end --代表右大括号,结束
--语句结束符
自定义符号
--将临时修改修正过来
Delimiter;
delimiter $$
create trigger after_order after insert on my_order for each r
begin
--触发器内容开始
update my_goods set inv = inv -1 where id = 2;
end
--结束触发器
$$
--修改临时语句结束符
delimiter;
可以查看触发器创建语句
show create trigger 触发器名字;
触发器不能修改,只能先删除,后新增
drop trigger 触发器名字;
代码执行结构之分支结构
在MySQL中只有if分支
基本语法
if 条件判断 then
--满足条件要执行的代码
else
--不满足条件要执行的代码
end if;
代码执行结构之循环结构
while 循环(没有for循环)
while 条件判断 do
-- 满足条件要执行的代码
-- 变更循环条件
end while;
循环控制:在循环内部进行循环判断和控制
MySQL中没有对应continue和break,但是有替代品
Iterate:迭代,类似continue,后面的代码不执行,循环重新来过
Leave:离开,类似break,整个循环结束
函数
讲一段代码块封装到一个结构中,在需要执行代码块的时候,调用结构执行即可(代码复用)
函数分为两类:系统函数和自定义函数
自定义函数
函数要素:函数名,参数列表(形参和实参),返回值,函数体(作用域)
--创建语法
create funtion 函数名([形参列表]) return 数据类型 --规定要返回的数据类型
begin
--函数体
--返回值:return 类型(指定数据类型);
end
--创建函数
create funtion display1() returns int
return 100;
注意是returns,不是return
删除函数(函数只能先删除后新增,不能修改)
语法:Drop function 函数名;
查看函数
查看函数的创建语句
函数的参数
参数分为两种:
定义的参数为形参,调用时的参数叫实参(实参可以是数值也可以是变量),形参:要求必须指定数据类型
function 函数名(形参名字 字段类型)returns 数据类型
作用域
MySQL中的作用域与js中的作用域完全一样
全局变量可以在任何地方使用;局部变量只能再函数内部使用
全局变量:使用set关键字定义,使用@符合标志
局部变量:使用declare关键字声明,没有@符号,所有的局部变量的声明,必须在函数体开始之前
存储过程
存储过程是一种没有返回值的函数,是一种用来处理数据的方式
create procedure 过程名字([参数列表])
begin
--过程体
end
调用存储过程
存储过程没有返回值:select是不能访问的
存储过程有一个专门的调用关键字:call
存储过程只能先删除,后新增
drop procedure 存储过程名;
--过程参数
delimiter $$
create procedure pro1(in int_1 int,out int_2 int,inout int_3 int)
begin
--先查看三个变量
select int_1,int_2,int_3; --int_2的值一定是null
end
$$
delimiter;
--drop PROCEDURE pp;
/*******************************************************************************
中文名称: 生成系统健康运行指标
调用方法: SCYW.P_AUTONEWSYSTEMRUNINGTIME
作 者: LIHAIPENG
创建时间: 2016-01-31
输入参数: IN_THISTIME : IMS取值时传入的时间戳
返 回 值: OUT_CODE : 返回类型 1为成功
OUT_MSG :返回错误信息
简要说明:
修改记录:
*******************************************************************************/
create procedure pp(in IN_THISTIME datetime,out OUT_CODE VARCHAR(8),out OUT_MSG VARCHAR(256)) BEGIN
-- 本次取值时间
DECLARE V_THISTIME int;
-- 上次取值时间
DECLARE V_LASTTIME varchar(256);
-- 上次取值
DECLARE V_LASTVALUE varchar(256);
-- 两次取值时间差
DECLARE V_INCREMENT varchar(256);
-- 最新健康时间
DECLARE V_JKSJ varchar(256);
-- IMS集成指标缓存表中健康时长指标的记录条数
DECLARE V_JKZBCOUNT varchar(256);
set V_THISTIME := DATE_FORMAT(IN_THISTIME, 'yyyy-mm-dd hh24:mi:ss');
SELECT COUNT(*)
INTO V_JKZBCOUNT
FROM c_cons c
WHERE c.cons_no = '9854032859';
-- 如果表中没有系统健康时长的记录,则插入一条
IF V_JKZBCOUNT < 1 THEN
INSERT INTO khcnlgl.test
(id, name, date)
VALUES
('BusinessSystemRunningTime',
'系统健康运行时长(s)',
'0');
ELSE
-- 获取上次取值的时间和指标值
SELECT c.cons_name, c.ELEC_ADDR
INTO V_LASTVALUE, V_LASTTIME
FROM c_cons c
WHERE c.cons_no = '9854032859'
AND ROWNUM = 1;
IF V_LASTVALUE IS NULL THEN
set V_LASTVALUE := '0';
END IF;
IF V_LASTTIME IS NULL THEN
-- 如果上次取值时间为空值,说明检修后清空后第一次ims取值。把取值时间为当前时间
set V_LASTTIME := V_THISTIME;
END IF;
-- -- 求两次取值的时间差
-- SELECT TO_NUMBER(V_THISTIME - V_LASTTIME) * 24 * 60 * 60
-- INTO V_INCREMENT
-- FROM DUAL;
-- -- 如果时间差值小于0则需按0计算
-- IF V_INCREMENT < 0 THEN
-- V_INCREMENT := 0;
-- V_JKSJ := TO_NUMBER(V_LASTVALUE) + V_INCREMENT;
-- ELSE
-- V_JKSJ := TO_NUMBER(V_LASTVALUE) + V_INCREMENT;
-- END IF;
--
-- -- 向IMS集成指标历史记录表中插入上次的指标记录
-- INSERT INTO SCYW.T_DW_JK_IMS_PARAM_HISTORY
-- (OBJ_ID,
-- DEPART_ID,
-- KPINAME,
-- DESCRIPTION,
-- KPIVALUE,
-- OPERATETIME,
-- NOTE,
-- FREQUENCY,
-- MESSAGE,
-- KPIFZ,
-- KPIFM,
-- SFMX)
-- SELECT PKG_GG_UTIL.F_GET_UUID,
-- DEPART_ID,
-- KPINAME,
-- DESCRIPTION,
-- KPIVALUE,
-- OPERATETIME,
-- NOTE,
-- FREQUENCY,
-- MESSAGE,
-- KPIFZ,
-- KPIFM,
-- SFMX
-- FROM SCYW.T_DW_JK_IMS_PARAM
-- WHERE KPINAME = 'BusinessSystemRunningTime';
--
-- -- 更新IMS集成指标缓存表
-- UPDATE SCYW.T_DW_JK_IMS_PARAM
-- SET KPIVALUE = to_char(V_JKSJ), OPERATETIME = V_THISTIME
-- WHERE KPINAME = 'BusinessSystemRunningTime';
--
-- -- 插入日志
-- INSERT INTO SCYW.T_DW_JK_IMS_LOG
-- (OBJ_ID, KPINAME, KEPCAPTION, STARTTIME, ENDTIME, MESSAGE)
-- VALUES
-- (SCYW.PKG_GG_UTIL.F_GET_UUID(),
-- 'BusinessSystemRunningTime',
-- '系统健康运行时长(s)',
-- V_THISTIME,
-- V_THISTIME,
-- '开始时间:' || V_THISTIME || ',当前时间:' || V_THISTIME || ',健康时长:' ||
-- to_char(V_JKSJ));
END IF;
COMMIT;
set OUT_CODE := '1';
-- exception
-- when others then
-- OUT_CODE := '0';
-- OUT_MSG := '错误日志:' || sqlcode || sqlerrm;
-- rollback;
--
-- INSERT INTO T_DW_JK_IMS_LOG
-- (OBJ_ID, KPINAME, KEPCAPTION, STARTTIME, ENDTIME, MESSAGE)
-- VALUES
-- (SCYW.PKG_GG_UTIL.F_GET_UUID(),
-- 'BusinessSystemRunningTime',
-- '系统健康运行时长(s)',
-- V_THISTIME,
-- V_THISTIME,
-- OUT_MSG);
-- COMMIT;
END;