事务
事务的ACID(acid)属性
➢1. 原子性( Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
➢2.一 致性( Consistency)
事务必须使数据库从一个- -致性状态变换到另外-一个一致性状态。
➢3.隔离性(Isolation)
事务的隔离性是指- 一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
➢4.持久性( Durability)
持久性是指一一个事务一 旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
事务的创建
- 隐式事务:事务没有明显的开启和结束的标记
比如insert、update、 delete语 句
delete from 表 where id =1; - 显式事务:事务具有明显的开启和结束的标记
前提:必须先设置自动提交功能为禁用
set autocommit=0; - 查看自动提交是否开启
SHOW VARIABLES LIKE ’ autocommit ’ ;
演示事务的使用步骤
-
#开启事务
SET autocommit=0;
START TRANSACTI ON; -
#编写一组事务的语句
UPDATE account SET balance = 1000 WHERE username= 张无忌,;
UPDATE account SET balance = 1000 WHERE use rname= "赵敏”; -
结束事务
ROLLBACK;
#commit;
事务隔离级别
隔离级别 | 描述 |
---|---|
READ UNCOMMTTED(读未提交数据) | 允许事务读取未被其他事物提交的变更脏读,不可重复读和幻读的问题都会出现 |
READ COMMTED(读已提交数据) | 只允许事务读取已经被其它事务提交的变更.可以避免脏读,但不可重复读和幻读问题仍然可能出现 |
REPEATABLE READ(可重复读) | 确保事务可以多次从一个字段中读取相同的值在这个事务持续期问,禁止其他事物对这个字段进行更新.可以避免脏读和不可重复读,但幻读的问题仍然存在. |
SERIALIZABLE(串行化) | 确保事务可以从一个表中读取相同的行在这个事务持续期问,禁止其他事务对该表执行插大.更新和删除操作.所有并发问题都可以避免,但性能十分低下. |
➢脏读:对于两个事务T1,T2, T1读取了已经被T2更新但还没有被提交的字段.之后,若T2回滚,T1读取的内容就是临时且无效的.
➢不可重复读:对于两个事务T1, T2,T1读取了一个字段,然后T2更新了该字段.之后, T1再次读取同一个字段,值就不同了。
➢幻读:对于两个事务T1, T2, T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行.之后,如果T1再次读取同一个表,就会多出几行.
-
对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:
-
数据库事务的隔离性:数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题.
-
一个事务与其他事务隔离的程度称为隔离级别.数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一 致性就越好,但并发性越弱.
-
每启动-一个mysql程序,就会获得一个单独的数据库连接.每个数据库连接都有一.个全局变量@@tx_isolation,表示当前的事务隔离级别.
-
查看当前的隔离级别: SELECT @@tx_ _isolation;
-
设置当前mySQL连接的隔离级别:
➢set transaction isolation level read committed; -
设置数据库系统的全局的隔离级别:
➢set global transaction isolation level read committed;
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted | V | V | V |
read committed | x | V | V |
repeatable read | x | x | V |
serializable | x | x | x |
- mysq1中默认第三个隔高级别 repeatable read
- oracle中默认第二个隔高级别 read committed
savepoint
#3.演示savepoint的使用
SET autocomnit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25p
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;单 回滚到保存点
视图
- 含义:虚拟表,和普通表一样使用
mysq15.1版本 出现的新特性,是通过表动态生成的数据 - 重用sql语句
简化复杂的sql操作,不必知道它的查询细节
保护数据,提高安全性
$案例:查询姓张的学生名和专业名
SELECT s tuname , majorname
FROM stuinfo s
INNER JOIN major m ON s. 'majorid'= m.'id'
WHERE s.‘stuname’ LIKE '%张%' ;
创建视图
CREATE VIEW v1
AS
SELECT stuname , maj orname
FROM stuinfo s
INNER JOIN major m ON s.'majorid'= m. id ;
SELECT * FROM v1 WHERE stuname LIKE '张号';
删除视图
DROP VIEW 视图名;
查看试图
DESC 视图名;
变量
一、系统变量,
说明:
变量由系统提供的,不是用户定义,属于服务器层面使用的语法:
注意:
如果是全局级别,则需要加global, 如果是会话级别,则需要加session, 如果不写,则默认session
- 1、查看所有的系统变量
show global 【session】 variables; - 2、查看满足条件的部分系统变量
show globaI 【session】 variables like ’%char%‘; - 3、查看指定的某个系统变量的值
select @@global 【session】 . 系统变量名; - 4、为某个系统变量赋值
方式一;
set globall 【session】 系统变量名 =值;
方式二:
set eglobal【session】 **.**系统变量名=值;
》 全局变量
#①查看所有的全局变量
SHOW GLOBAL VARIABLES ;
#②查看部分的全局变量
SHOW GLOBAL VARIABLES LIKE '%char%' ;
#③查看指定的全局变量的值
SELECT B@global . autocommit ;
SELECT @@tx_isolation;
#④为某个指定的全局变量赋值
SET @@global . autocommit=0;
#1》 全局变量
作用域:服务器每次启动将为所有的全局变量赋初始值,针对于所有的会话(连接)有效,但不能跨重启
》 会话变量
作用域:仅仅针对于当前会话(连接)有效
- #①查看所有的会话变量
SHOW VARIABLES ;
SHOW SESSION VARIABLES; - #②查看部分的会话变量
SHOW VARIABLES LIKE ‘%chark%’ ;
SHOW SESSION VARIABLES LIKE ‘%char%’ ; - #③查看指定的某个会话变量
SELECT @@tx_isolation;
SELECT @@session.tx_isolation; - #④为某个会话变量赋值
方式一:
SET @@tx_isolation= ’ read-uncommitted’ ;
方式二:
SET SESSION tx_isolation ='read-comnitted ’ ;
自定义变量
- 说明:变量是用户自定义的,不是由系统的
使用步骤:
声明
赋值
使用(查看、比较、运算等)
用户变量
-
作用域:针对于当前会话(连接)有效,同于会话变量的作用域应用在任何地方,也就是begin end 里面或begin end外面
-
赋值的操作符:= 或 :=
-
#①声明并初始化
SET @用户变量名 = 值;或
SET @用户变量名 := 值;或
SELECT @用户变量名 := 值;
- #②赋值(更新用户变量的值)
- 方式一~:通过SET或SELECT
- SET @用户变量名=值;或
SET @用户变量名:=值;或
SELECT B用户变量名:=值;
- SET @用户变量名=值;或
- 方式一~:通过SET或SELECT
- 方式二:通过SELECT INTO
SELECT字段~ INTO变量名 FROM 表 ;
#案例:
#声明并初始化
SET
@name= "john';
SET @name=100;
SET Bcount=1 ;
#赋值
SELECT COUNT (*) INTO @count
FROM employees ;
#查看
SELECT @count ;
#③使用
SELECT 局部变量名;
局部变量
-
作用域:仅仅在定义它的begin end中有效
-
应用在begin end中的第一句话I
-
#①声明
DECLARE变量名类型;
DECLARE变量名类型DEFAULT 值; -
#②赋值
方式一:通过sET或SELECT
SET局部变量名=值;或
SET局部变量名:=值;或
SELECT @局部变量名:= 值; ,
方式二:通过SELECT INTO
SELECT 字段 INTo 局部变量名 FROM表; -
对比用户变量和局部变量:
变量 | 作用域 | 定义和使用的位置 | 语法 |
---|---|---|---|
用户变量 | 当前会话 | 会话中的任何地方 | 必须加@符号,不用限定类型 |
局部变量 | BEGIN END中 | 只能在BEGIN END中,且为第一句话 | 一般不用加@符号,需要限定类型 |
#案例:声明两个变量并赋初始值,求和,并打印
#1.用户变量
SET @m=1;
SET @n=2 ;
SET @sum = @m+@n;
SELECT G sum;
存储过程
- 含义:一组预先编译好的SQL语句的集合,理解成批处理语句
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
一、创建语法
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一組合法的SQL语句)
END
注意:
1、参数列表包含三部分
参数模式 ---- 参数名 ----- 参数类型
举例:
IN stuname VARCHAR (20)
参数模式:
IN:该参数可以作为输入,也就是该参数需要调用方传入值
OUT: 该参数可以作为输出,也就是该参数可以作为返回值
INOUT:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值
2、如果存储过程体仅仅只有一-句话,BEGIN END可以省略
- 存储过程体中的每条SQL语句的结尾要求必须加分号。
- 存储过程的结尾可以使用DELIMITER 重新设置
- 语法:
DELIMITER 结束标记
案例:
DELIMITER $
1、创建无参的存储过程
DELIMITER $
CREATE PROCEDURE myp1 ()
BEGIN
INSERT INTO admin (use rname, 'pas sword ' )
VALUES('john1", *0000*), (lily', *0000'), ('rose', *0000"), ("jack", *0000"), ('tom', '0000') ;
END $
#调用
CALL myp1 () S
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 $
#调用
CALI 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 = use rname
AND admin. password = PASSWORD;
SELECT IE (result>0, '成功',‘失败');#使用
END $
#调用
CALL myp3('张飞', *8888')$
3、创建带out模式的存储过程
#案例1:根据女神名,返回对应的男神名
CREATE PROCEDURE myp5 (IN beautyName VARCHAR(20) , OUT boyName VARCHAR (20) )
BEGIN
SELECT bo. boyName INTO boyName
FROM boys bo
INNER JOIN beauty b ON bo.id = b.boyfriend_ id
WHERE b. name =beautyName;
END $
#调用
CALL myp5 ("小昭" , @bName) $
SELECT @bNameS
#案例2:根据女神名,返回对应的男神名和男神魅力值
CREATE PROCEDURE myp6 (IN beautyName VARCHAR(20) , OUT boyName VARCHAR(20) , OUT userCP INT )
BEGIN
SELECT bo.boyNase ,bo.usexCP INTo boyName , userCP
PROM boys bo
INNER JOIN beauty b ON bo.id = b.boyfriend_ id
WHERE b . name = beautyName ;
END $
#调用
CALL myp6(*小昭", @bName, Busercp)$
#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) S
SELECT @m, @n $
二、删除存储过程
#语法: drop procedure 存储过程名
DROP PROCEDURE p1 ;
DROP PROCEDURE p2,p3;#x (错误)
三、查看存储过程的信息
DESC myp2;x(错误)
SHOW CREATE PROCEDURE myp2 ;
函数
一、创建语法
CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
函数体
END
注意:
- 1.参数列表包含两部分:
参数名参数类型 - 2.函数体:肯定会有return语句, 如果没有会报错
如果return语句没有放在函数体的最后也不报错,但不建议
return值; - 3.函数体中仅有一句话,则可以省略begin end
- 4.使用delimiter语句设置结束标记
----------------------------案例演示----------------------------
#1.无参有返回
#案例:返回公司的员工个数
CREATE FUNCTION myf1 () RETURNS INT
BEGIN
DECLARE c INT DEFAULT 0;定义变量
SELECT COUNT (*)
INTO c
FROM employees ;
RETURN C;
LEND $
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 tsal ;
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')$
一、创建函数,实现传入两个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)$
*三、查看函数
SHOW CREATE FUNCTION myf3;
#四、删除函数
DROP FUNCTION myf3;[