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 表名

distinctselect和字段列表之间,用于去处多表之间重复数据

单列:

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子句的语法

警告:不能使用别名

wherefrom执行前面,也在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 andnot between and
is nullis not null
innot in 注意null值
likenot 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

执行顺序:

  • from
  • where 不能使用字段别名,组函数
    • select
      • group by
        • having
          • order by
            • limit

子查询

  • 如果一个select语句嵌入到另一个SQL语句(例如selectinsertupdatedelete语句)中,那么该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 语句;
  • 函数体可以是简单地selectinsert语句
  • 函数体如果是复合结构,可以用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\G show 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;

其中: 触发时间:beforeafter 触发事件:insertupdatedelete for 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语句:

beginset autocommit=1;start transaction;rename tabletruncate等语句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

  1. 产生结果集

  2. 不产生结果集

评论

评论加载中……