MySQL操作
create database databasename;
数据库管理
创建数据库
create database databasename;
查看数据库:
show databases;
查看指定数据库创建信息
show create database dbname;
选择数据库
use dbname;
删除数据库
drop database dbname;
表管理
表描述
desc tablename;
insert into tablename(字段列表) values(值列表);
select * from tablename;
删除表
drop table tablename;
创建表:
create table 表名(
字段名1 数据类型 [约束条件],
字段名2 数据类型 [约束条件],
...
[其他约束条件],
[其他约束条件]
)其他选项;约束类型
primary key #主键约束
not null #非空约束
default #默认值约束
unsigned #非负约束
unique #唯一约束//可以为空,可以空值多个,因为null!=null
foreign key #外键约束
references #外键约束 参照主键约束:
* 单一字段当主键
直接在该字段后面或其他约束条件之后加上关键字primary key
字段名 数据类型 [其他约束条件] primary key
*多个字段组合当主键
primary key(字段名1,字段名2)主键唯一非空
- 外键约束:
主表:提供数据的表
从表:使用主表数据的表
外键字段的值:要么为NULL,要么来自主表的主键
constraint 约束名 foreign key(从表中的字段名或字段列表) references 主表(字段名或字段列表);
约束名:给约束命个名字
reference:引用或参考
自增长字段:
字段名 数据类型 auto_increment;
数据类型:
整数类型:
tinyint smallint mediumint int bigint
精确小数类型:
decimal(length,precision)
* length决定该小数的最大位数
* precision用于设定精度(小数后面的数字位数)
* decimal(5,2)浮点数类型:
float double
字符串类型:
定长字符串char(n)
最多容纳字符数255
变长字符串varchar(n)
n取值与字符集有关日期时间类型:
date datetime time
data:三个字节 从‘1000-01-01’~’9999-12-31’
格式:‘YYYY-MM-DD’
datetime:八个字节
范围:‘1000-01-01 00:00:00’~’9999-12-31 23:59:59’
格式:YYYY-MM-DD hh:mm:ss
time:
取值范围‘-838:59:59’~’838:59:59’
格式hhh:mm:ss创建实例
create table scores(
线代 int unsigned not null default 0,
离散 int unsigned not null default 0,
高数 int unsigned not null default 0,
序号 int ,
name char(20),
primary key(序号,name)
);复制表结构:
(没有数据,不包含外键约束
create table 表名 like 源表名;
完全复制数据和结构:
(数据备份
create table 表名 select * from 源表名
//////////////////////////////////////
DML操作(增删改
向表中插入一条记录
insert into tablename(字段列表) values(值列表);
批量插入数据
插入多条记录
insert into tablename(字段列表) values(值列表1),(值列表2),(值列表3);
insert … select语句
将源表的查询结果添加到目标表中
insert into 目标表名[(字段列表1)] select (字段列表2) from 源表 where 条件表达式;
#where 字段名>数值 #where 字段名>数值 and 字段名>=数值 #where 字段名>数值 or 字段名=数值
表记录的更新
update 表名 set 字段名1=值1[,字段名2=值2] [where 条件表达式]
表记录的删除:
delete语句
删除表数据
delete from 表名 [where表达式]; n
truncate语句
截断表,相当于没有where的delete
truncate table 表名;
区别
只要截断的是主表,truncate不行,delete可以
truncate对于自增长删除后从头开始,delete不恢复初始值
查询语句
select语句
select 字段列表 from 数据源 [where表达式][group by分组字段][having条件表达式]][order by排序字段[asc|desc]]
字段列表:要检索的字段
数据源:检索的表或视图
where子句:指定记录过滤条件
group by子句:检索数据进行分组
having子句:分组后数据进行筛选
order by子句:结果集进行排序(asc升序(默认)desc降序)使用select返回指定字段列表
字段列表的指定方式:
| 字段列表 | 说明 |
|---|---|
| * | 字段列表为数据源的全部数据 |
| 字段列表 | 逗号隔开的字段列表 |
| 表名.* | 多表查询时,指定某表的全部字段 |
| 表名.字段 | 多表查询时,指定某表的某个字段 |
| 表达式 | 表达式可以包括算术运算,函数等 |
使用select version(),now();
起个别名:select version() as 版本,now() as 当前时间;
起别名:字段名称 [as] 别名as可省
基本查询语句
使用关键字distinct过滤结果集中重复数据
select distinct 字段列表 from 表名
distinct在select和字段列表之间,用于去处多表之间重复数据
单列:
select distinct table_schema from information_schema.tables
多列:
select distinct table_schema,table_type from information_schema.tables
其中tables是数据库information_schema中的一张表
使用limit线代返回行数
分页
select 字段列表 from 表名 limit [start],length;
start:表示从第一行记录开始检索,缺省为0,表示第一行
length:表示要检索的行数
表连接(用于制作新的数据源
内连接:
符合关联条件的被检索出来,不符合的被过滤掉
外连接的结果集 = 内连接结果集 + 匹配不上的记录
select 字段列表 from 表1 [inner] join 表2 on 关联条件
select student.student_no,student.student_no,classes.class_no from student inner(可写可不写) join classes on student.class_no = classes.class_no;表的别名:减少长度
select s.student_no,s.student_no,c.class_no from student s(别名) join classes c(别名) on s.class_no = c.class_no;警告:一旦使用别名,在当前语句中就不能用当前名
如果连接的两张表没有重名的字段,可以省略字段前的表名或别名,否则必须加表名修饰
三表连接:
select 字段列表 from 表1 [inner] join 表2 on 关联条件1 join 表3 on 关联条件2;
外连接:
- 左外连接:
- 左外连接的结果集=内连接的结果集+左表中匹配不上的记录
select 字段列表 from 左表 left [outer] join 右表 on 关联条件
- 右外连接:
- 右外连接的结果集=内连接的结果集+右表中匹配不上的记录
select 字段列表 from 右表 right [outer] join 左表 on 关联条件
保护的对象不同,学生作为左表保护没有班级的学生
where子句的语法
警告:不能使用别名
where 在from执行前面,也在group by 前面
比较运算符:
> < = <= >= != <>以下为mysql提供的语句:
between … and
判断表达式的值是否在给定的闭区间
表达式 between 值1 and 值2
is null
判断表达式的值是否为空
表达式 is null
in
判断表达式的值是否位于一个列表中
表达式 in(值1,值2,...)
like
判断表达式的值是否符合给定的模式
表达式 like ‘模式’
%:匹配任意长的任意字符
__:匹配一位任意字符
张%一>张某人
要检索内容中包含__:
\_转义字符
自定义转义字符(escape)都支持
like ‘user#__%’ escape ‘#’;
逻辑运算符:
与运算and
逻辑表达式1 and 逻辑表达式2
where 关联条件1 and 关联条件2
或运算or
逻辑表达式1 or 逻辑表达式2
where 关联条件1 or 关联条件2
使用where子句实现三表连接:
select * from 表1,表2,表3
where 关联条件1 and 关联条件2;
非运算not
not 逻辑表达式 或者
!(逻辑表达式)
where 关联条件1 not 关联条件2
运算符取反
| > | <= |
|---|---|
| < | >= |
| = | != / <> |
| between and | not between and |
| is null | is not null |
| in | not in 注意null值 |
| like | not like |
order by子句
按照给定的字段或字段列表对结果集进行排序
order by {col_name|expr|position} {[asc]|desc} [,{col_name|expr|position} {[asc]|desc},...]
asc 升序,缺省方式
desc 降序
col_name用于排序字段名
expr表达式
position字段所在位置
组函数(聚合函数)
- 常见的组函数
cout(exp)返回exp非空值的数量max(exp)返回exp的最大值min(exp)返回exp的最小值sum(exp)返回exp的累加和avg(exp)返回exp的平均值
exp指的是字段名
只有count能用*
count(*)
组函数对null值忽略
组函数的参数可以用distinct修饰
select count(distinct score) 不重复的分数数量 from score;
基本用法:
select count(*) 记录数 from score;group by子句
group by子句将查询的结果按照某个字段(或多个字段)进行分组(字段值相同的记录作为一个分组),通常与组函数(聚合函数)一起使用
group by 字段列表[having 条件表达式]
有group by语句的select后面只能有分组字段 ,组函数|聚合函数,依赖于分组字段的字段,比如student_name依赖于student_no
列出每个学生总分:
select student_no,sum(score) 总分,avg(score) 平均分 from test group by student_no;要解决where执行在分组之前不能使用组函数的问题,我们就只能使用having 子句
having 条件表达式
select student_no,sum(score) 总分,avg(score) 平均分 from test group by student_no having avg(score)>50;语法顺序:
- selet
- from
- where
- group by
- having
- order by
- limit
- order by
- having
- group by
- where
- from
执行顺序:
- from
- where 不能使用字段别名,组函数
- select
- group by
- having
- order by
- limit
- order by
- having
- group by
- select
子查询
-
如果一个
select语句嵌入到另一个SQL语句(例如select、insert、update、delete语句)中,那么该select语句称为”子查询”,包含子查询的语句称为”主查询”。 -
为了标记子查询和主查询之间的关系,通常将子查询写在小括号内。
-
子查询可以用在主查询的
where子句、having子句、select子句或者from子句中。
子查询返回单值
条件表达式中可以使用比较运算符 示例: 列出考试成绩低于平均分的信息,包括学号、课程号和成绩 查询平均分
select avg(score) from choose;结果为65 把上一条语句的结果作为条件,进行检索select student_no, course_no, score from choose where score < 65;把两条语句合并select student_no, course_no, score from test where score < (select avg(score) from choose);
子查询返回多值
条件表达式中的运算符可以使用in、not in等 示例:检索没有开设选修课的教师的信息 。使用表连接 select t.teacher_no教师工号,t.teacher_name姓名
from teacher t left join course c on t.teacher_no=c.teacher_no where c.course_no is null;。使用子查询select teacher_no教师工号,teacher_name 姓名 from teacher where teacher _no not in(select teacher _no from course);
from子句中的子查询 每一个select语句可以看成是一个虚拟的内存表,可以在结果集的基础上进行进一步的查询 示例:
检索表的数量多于50的数据库的信息
select *from( select table_schema, count(table_name) cnt from information_schema.tables group by table_schema) db where cnt>50;
db是别名检索考试成绩比自己的平均分高的课程的信息
select c.student_no,c.course_no,c.score,a.a_score from choose c, ( select student_no s_no,avg(score) a _score from choose group by s_no) a where c.student_no = a.s_no and c.score > a.a _score;
索引index 创建索引 >创建索引的方式有两种: 创建表的同时创建索引、在已有表上创建索引 创建表的同时创建索引 语法:
create table表名(
字段名1 数据类型[约束条件],
[其他约束条件],
[unique|fulltext] index[索引名](字段名[(长度)])
unique唯一索引
fulltext全文索引
长度指字符串前多少位作为索引(前缀索引
在已有表上创建索引
语法:
create [unique|fulltext] index 索引名on表名(字段名[(长度)]);数据库会自动为主键,外键,唯一字段设置索引
查看索引
>语法
show index from 表名\G
>示例
show index from student\G
删除索引
>语法
drop index索引名on表名;
示例
drop index ix_stuname on student;
视图view
创建视图 视图中保存的仅仅是一条select语句,该select语句的数据源可以是基表,也可以是另一个视 图。创建视图的语法格式如下:
create view 视图名[(视图字段列表)]
as
select语句;查看视图
使用查看表结构的方式查看视图的定义
desc 视图名;> MySQL命令show tables;>MySQL系统数据库information_schema的views表存储了所有视图的定义,使用下面的select语句可以查看所有视图的详细信息select * from information_schema.views\G
作用
- 使操作变得简单
- 避免数据冗余
- 增强数据安全性
- 提高数据的逻辑独立性
MySQL编程基础
用户会话变量
使用set命令定义用户会话变量,并为其赋值
set @变量名 = 值[,@user_var2=expr2];
加@是作为用户会话变量使用的,不加@是系统变量
使用select语句定义会话变量,并为其赋值
select @user_var1:=expr1[,@user_var2:=expr2]1或
select expr1,expr2,...into @user_var1,user_var2...2
显示:select @user_var1;
select @stu_cnt:=(select count(*) from student);可以简化为:
select @stu_cnt:=count(*) from student;
select …into结果集写法
select count(*) into @stu_cnt from student;
局部变量
declare 变量名 数据类型;
局部变量必须定义在存储程序中,且作用范围也只在存储程序中
定义是赋初值:
declare 变量名 数据类型 default 值;
begin-end语句块(类似大括号)
[开始标签]begin
[局部]变量的声明;
错误触发条件的声明;
游标的声明;
错误处理程序的声明;
业务逻辑代码;
end[结束标签];开始标签和结束标签名字相同,有的业务需要
在MySQL中,单独使用begin-end语句块没有任何意义,只有将其封装到存储过程、函数、触发器以及事件等存储程序内部才有意义
自定义函数
create function 函数名(参数1,参数2……)returns 返回值的数据类型
函数体
return 语句;- 函数体可以是简单地
select或insert语句 - 函数体如果是复合结构,可以用begin……end语句
- 复合结构可以包含声明,循环,控制结构等
delimiter $$
create function my_fun2() returns int
no sql
return 8;
$$
delimiter ;对于8.0MySQL:
要设置信任开发者,有两种方法
1:修改配置文件my.ini(D:\MySQL\MySQL Server 8.0\Data)
在[mysqld]里面加上log-bin-trust-function-creators=1
2:设置修改全局变量
set GLOBAL log_bin_trust_function_creators=1;
3:在创建子程序(存储过程、函数、触发器)时,声明为DETERMINISTIC(确定性)或NO SQL 与READS SQL DATA中的一个
格式:
CREATE DEFINER = CURRENT_USER PROCEDURE `new_pro`()
DETERMINISTIC
BEGIN
#Routine body goes here...
END;
CREATE DEFINER = CURRENT_USER FUNCTION `new_FUNC`()
RETURNS VARCHAR(20)
DETERMINISTIC
BEGIN
#Routine body goes here...
END;自定义函数是数据库的对象,因此,创建自定义函数时,需要指定该自定义函数属于哪个数据库 同一个数据库内,自定义函数不能和已有的函数名(包括系统函数名)重名 函数必须指定返回值数据类型,且须与return语句中的返回值的数据类型相匹配
函数体
自定义结束符号:delimiter 符号
delimiter翻译为分隔符e
delimiter $$
delimiter ;
查看函数
查看当前数据库中所有的自定义函数的信息
show function status\Gshow function status like 模式\G
查看指定数据库中的所有自定义函数名
select name from mysql.proc where db ='数据库名'and type= 'function';
查看指定函数名的详细信息
show create function 函数名\G
删除函数
drop function函数名;
流程控制语句
MySQL提供了简单的流程控制语句,其中包括条件控制语句以及循环语句。这些流程控制语句通常放在begin-end语句块中使用 条件控制语句:
if 语句
case 语句
循环语句:
while循环:
repeat循环
loop循环
if语句
语法格式
if 条件表达式1 then 语句块1;
[elseif 条件表达式2 then 语句块2;]...
[else 语句块n;]
end if;case语句
case语句用于实现比if语句分值更为复杂的条件判断,语法格式如下:
case 表达式
when valuel then 语句块1;
when value2 then 语句块2;
when value3 then 语句块3;
...
else 语句块n;
end case;循环语句 MySQL提供了3种循环语句,分别是while、repeat以及loop。除此外,MysQL 还提供了iterate语句以及leave语句,用于循环的内部控制
while循环
while 语句语法格式如下:
[循环标签:]while 条件表达式do
循环体;
end while[循环标签];leave语句
leave语句用于跳出当前的循环语句,语法格式如下:
leave 循环标签;
例如,创建函数,使用leave语句实现1.n(n>1)的累加使用while循环完成功能
...
add_num : while true do
seti =i+ 1;
set sum = sum + i;
if i=n then
leave add_num;
end if;
end while add_num;
...iterate语句
iterate语句用于跳出本次循环,继续进行下次循环。语法:
iterate 循环标签;
例如,创建函数,使用iterate语句实现从1.n(n>1)的偶数累加:
...
add_num: while i<n do
seti=i+ 1;
if i%2!=0 then iterate add_num;end if;
set sum = sum + i;
end while add_num;
...repeat语句
当表达式的值为false时反复执行循环,直到条件表达式的值为true
repeat语句的语法格式如下:
[循环标签:]repeat
循环体;
until 条件表达式
end repeat[循环标签];loop语句
由于loop循环语句本身没有停止循环的语句,因此loop通常借助leave语句跳出loop循环
loop循环的语法格式如下:
[循环标签]:loop
循环体;
if 条件表达式 then
leave 循环标签;
end if;
end loop[循环标签];系统函数
数字函数
求近似值函数
round(x);计算离x最近的整数。
round(x,d):计算离x最近的小数(d可以取负值)
truncate(x,d):截取到小数点y位(d可以取负值)
ceil(x):返回大于等于x的最小整数
floor(x):返回小于等于x的最大整数
随机函数
rand():返回随机数
字符串函数
char_length(x):获取字符串x的长度
length(x):
获取字符串x占用的字节数
concat(x1,x2….):用于将x1,x2等若干个字符串连接成一个字符串。
Itrim(x):用于去掉字符串x开头的所有空格字符。
rtrim(x):用于去掉字符串x结尾的所有空格字符。
trim(x):用于去掉字符串x开头以及结尾的所有空格字符。
left(x,n):返回字符串x的前n个字符。
right(x,n):返回字符串x的后n个字符。
upper(x):返回将字符串x中的所有字母变成大写字母的字符串。
lower(x):返回将字符串x中的所有字母变成小写字母耳朵字符串。substring(x,start,length):从字符串x的第start个位置开始获取length长度的字符串。
日期时间函数
-
获取MySQL服务器当前日期或时间函数
curdate();获取服务器当前日期curtime0:获取服务器当前时间:获取服务器当前日期和时间,并且允许传递一个<=6的整数值作为参数,从而获取更为精确的时间信息。 -
获取MySQL服务器当前日期或时间函数
year(x)、month(x)、 dayofmonth(x)、hour(x)、minute(x)、second(x)、microsecond(x)函数分别用于获取日期时间x的年、月、日、时、分、秒、微秒等信息。
条件控制函数
- if()函数
if(condition,v1,v2)函数中,condition为条件表达式,当condition的值为true时,函数返回V1的值,否则返回v2的值 - ifnull()函数
在
ifnull(v1,v2)中,如果v1的值为NULL,则该函数返回v2的值;如果v1的值不为NULL,则该函数返回v1的值
触发器
概念
触发器定义了一系列操作,这一系列操作称为触发程序,当触发事件发生时,触发程序会自动运行语法
create trigger 触发器名 触发时间 触发事件 on 表名 for each row
begin
触发程序
end;其中: 触发时间:
before、after触发事件:insert、update、deletefor each row:表示行级触发器,每影响一行触发一次,不影响就不触发
new :新值标识符 insert update
old :旧值标识符 update delete
new.字段 old.字段
可以使用触发器来是实现检查约束
delimiter $$
create trigger t before update on score for each row
begin
if new.physics_score>100||new.physics_score<0
then signal sqlstate 'ERROR' set message_text='错误的取值';
end if;
end;
$$
delimiter ;存储过程
创建存储过程的语法格式如下
create procedure 存储过程名(参数1,参数2….)
begin
存储过程语句块;
end;存储过程有3种类型的参数: in: 默认输入参数 out: 输出参数 inout: 既是输入参数,又是输出参数
特性:
comment:注释
contains SQL:包含SQL语句,但不包含读或写数据的语句
no sql:不包含sql语句
reads sql data:包含读数据的语句
modifiles sql data:包含写数据的语句
sql security {dediner|invoker}:指定谁有权限来执行过程体:
过程体由SQL语句构成
过程提可以是任意的SQL语句
过程提如果是复合结构则使用begin……end语句
复合结构可以包含声明,循环,控制语句创建不带参数存储过程
create procedure sql1() select version();调用:
call sql1();
没有参数可以这样
call sql1;创建含有IN类型参数的存储过程
create procedure findscore(in id char(10)) select * from score where student_name=id;调用call findscore('朱烨');
带有IN,OUT类型变量的存储过程
delimiter $$
create procedure findscore(in id char(10),out mlast int)
begin
select * from score where student_name=id;
select count(*) into mlast from score;
end
$$
delimiter ;修改存储过程:
alter procedure name()[characteristic…]
comment 'string'
|{contains sql|no sql|reads sql data|modifiles sql data}
|{sql security {definer|invoker}}查看存储过程的定义
语法:
show procedure status\G
查看某个数据库中的所有存储过程名
语法:
select name from mysql.proc where db='数据库名'and type='procedure';
查看指定数据库的指定存储过程的信息
>语法:
show create procedure get_choose_number_proc\G
删除存储过程
如果某个存储过程不再需要,则可以使用drop procedure语句将其删除,语法格式如下:
drop procedure [if exists] 存储过程名;
例如,删除get_choose _number _proc存储过程可以使用下面的SQL语句:
drop procedure get_choose number proc;
错误处理
自定义错误处理程序,使用declare关键字,语法格式
declare 错误处理类型 handler for 错误触发条件 自定义错误处理程序;
错误处理类型:continue,exit
continue会在处理完之后继续执行陈鼓,exit处理完之后就结束
错误触发条件:
- 预定义
- MySQL错误代码
- ANSI标准错误带代码
- 自定义错误触发条件
位置:在所有的变量声明之后,在MySQL语句之前
使用预定义的错误触发条件
预定义错误触发条件:sqlexception,sqlwarning,not found(分别是SQL语句出现错误,出现警告,将不存在的查询结果赋值给变量)
delimiter $$
create procedure findscore(in name char(10),out ss int)
begin
declare exit handler for not found select '未找到' error;
select physics_score into ss from score where student_name=name;
select ss score;
end;
$$
delimiter ;使用MySQL错误代码的错误触发条件
delimiter $$
create procedure insertscore(in name char(10),in score int)
begin
declare exit handler for 1452 select '没有这个学生信息' error;
insert into score values(name,score);
end;
$$
delimiter ;调用:call insertscore('sdfesf',89);
使用ANSI错误代码的错误触发条件
delimiter $$
create procedure insertscore(in name char(10),in score int)
begin
declare exit handler for slqstate `23000` select '没有这个学生信息' error;
insert into score values(name,score);
end;
$$
delimiter ;调用:call insertscore('sdfesf',89);
多个错误处理:
delimiter $$
create procedure insertscore(in name char(10),in score int)
begin
declare exit handler for 1452 select '没有这个学生信息' error;
declare exit handler for 1432 select '??' error;
insert into score values(name,score);
end;
$$
delimiter ;自定义错误触发条件:
自定义错误触发条件允许数据库开发人员为MySQL错误代码或者ANSI标准错误代码命名,语法格式如下:
declare 错误触发条件 condition for 错误代码;
上面案例中中的代码可以改为:
declare unique_error condition for 1062 ;
declare continue handler for unique_error;
begin
select'该教师已经提交了一门选修课! error;
end;游标
游标本质上是一种能从select结果集中每次提取一条记录的机制,因此游标与select语句息息相关
游标的作用是处理多行结果集
游标的使用步骤
声明游标:
declare 游标名 cursor for select语句;使用declare语句声明游标时,此时与该游标对应的select语句并没有执行,MySQL服务器内存中并不 存在与select语句对应的结果集。
这句只是给游标起一个名字并定义将来要处理的结果集
打开游标
open 游标名;使用open语句打开游标后,与该游标对应的select语句被执行,MySQL服务器内存中存放于select语句对应的结果集
游标的使用步骤 提取数据
语法:
fetch 游标名 into 变量名1,变量名2.….;变量名的个数必须与声明游标时使用的select语句结果集中的字段个数保持一致。每执行一次 fetch语句,从结果集中提取一行数据,同时游标向下移动一行。
关闭游标
close游标名;关闭游标的作用在于释放游标打开时产生的结果集,从而节省MySQL服务器的内存空间。游标 如果没有被明确的关闭,那么它将在被打开的begin-end语句块的末尾关闭。
create procedure update_score(c_no int)
begin
declare stu_no char(11);
declare grede int;
declare state char(10)
-- 声明游标
declare score_cur cursor for select student_no,score from choose where course_no=c_no;
declare continue handler for not found set state='error';
打开游标
open score_cur;
-- 循环提取游标(没有数据就会有错误)
update_score:loop
fetch score_cur into stu_no,grade;
if state = 'error' then
leave update_score
end if;
set grade=geade+5;
if grade>100 then
set grade = 100;
end if;
if grade between 59 and 60 then
set grade = 60;
end if;
update choose set score=grade where student_no=stu_no and couse_no=c_no;
end loop update_score;
-- 关闭游标
close score_cur;
end
关闭mysql自动提交
当前会话
显式关闭自动提交:
查看是否开启自动提交:
show variables like 'autocommit';
关闭:
set autocommit = 0;
隐式关闭自动提交:
start transaction;
transaction:事务
这种关闭并不会改变系统会话变量@@autocommit的值
事务控制语句
回滚
关闭MySQL自动提交之后,可以根据需要回滚(也叫撤销)更新操作
语法:rollback;
提交
MySQL自动提交一旦关闭,我们需要“提交”更新语句,才能将结果提交到数据库文件中,成为数据库永久的组成部分。
显式提交
语法:commit;
隐式提交:
MySQL自动提交关闭后,使用下面的MySQL语句:
begin、set autocommit=1;、start transaction;、rename table、truncate等语句ddl(create drop)、dcl(数据库语句)锁语句等
保存点
使用MySQL命令“savepoint 保存点名;”可以将事务回滚到保存点状态。
创建存储过程save_point_proc(),该存储过程撤销所有的insert语句
……
begin
declare continue handler for 1062
begin
rollback to B;
rollback
end;
start transaction;
insert into account values(null,,);
savepoint B;
insert into sccount values(null,'',);
commit;
……事务的ACID特性
事务的ACID特性原子性(Atongicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)4个英文单词的首字母组成。 原子性:
原子性用于标识事务是否完全地完成。一个事务的任何更新都要在系统上完成,如果由于某种原因出错,事务不能完成它的全部任务,那么系统将返回到事务开始前的状态。
一致性 事务的一致性保证了事务完成后,数据库能够处于一致性状态。如果事务执行过程中出现错误,那么数据库中的所有变化将自动地回滚,回滚到另一种一致性状态。
隔离性 同一时刻执行多个事务时,一个事务的执行不能被其他事务干扰。事务的隔离性确保多个事务并发访问数据时,各个事务不能相互干扰,好像只有自己在访问数据。
持久性 持久性意味着事务一旦成功执行,在系统中产生的所有变化将是永久的。
Footnotes
评论
评论加载中……