MySQL中DML语句和事务的概念

article/2025/9/12 22:11:03

ML语句

知识要点
DML语句
插入行到表中
删除表中的行
更新表中的行
控制事务

DML语句
DML:DATA MANIPULATION LANGUAGE(数据操纵语言),由INSERT、UPDATE、DELETE等语句构成,用来修改表中的数据

INSERT语句
1.带VALUES子句的INSERT语句
INSERT [INTO] tbl_name[(col_name,…)]
{VALUES | VALUE} (expr ,…),(…),…
用来把一个新行插入到表中
为和其它数据库保持一致,不要省略INTO关键字以及使用VALUES而不是value关键字
插入一行时,要求必须对该行所有的列赋值。但是赋值方式可以是显式赋值(直接给出值)和隐式赋值(由MySQL自动赋值)

2.在表名后面列出所有的列名
示例: 插入一个新的球队到teams表中
INSERT INTO teams(teamno,playerno,division)
VALUES(3,6,‘third’); ##需要一一对应,顺序一致

3.在表名后面省略所有的列名
这种写法要求VALUES子句中的值必须按照列在表结构中的顺序来一一赋值
示例:INSERT INTO teams
VALUES(4,104,‘third’);在这里插入图片描述
4.在表名后面只列出部分的列名
所有没有明确赋值的列,将通过隐式赋值自动得到null值
示例: 添加一个新球员
INSERT INTO players(playerno,NAME,initials,sex,joined,street,town)
VALUES(611,‘Jones’,‘GG’,‘M’,1997,‘Green Way’,‘Stratford’);

5.使用字面量NULL给列赋空值
示例:
INSERT INTO teams
VALUES(4,104,null); ##注意null值不要加引号

  1. VALUES子句中除了字面量,还可以使用函数、计算、标量子查询等
    示例:
    CREATE TABLE totals(
    numberplayers INTEGER NOT NULL,
    sumpenalties DECIMAL(9,2) NOT NULL); ##创建表
    INSERT INTO totals(numberplayers,sumpenalties)
    VALUES((SELECT count(*) FROM players), ##子查询的值必须是一行一列
    (SELECT sum(amount) FROM penalties));
    注意:子查询必须放在单独的小括号中在这里插入图片描述
    7.一条INSERT语句可以插入多个行
    示例:添加4个新的球队
    INSERT INTO teams(teamno,playerno,division)
    VALUES (6,7,‘third’),
    (7,27,‘fourth’),
    (8,39,‘fourth’),
    (9,112,‘sixth’);
    注意:这种语法只要有一行出错,则插入全部取消在这里插入图片描述8.INSERT语句中可以使用IGNORE选项来当INSERT语句出错时,不显示错误消息。INSERT语句不会执行在这里插入图片描述主键列不允许数据重复

9.带子查询的insert语句
带子查询的INSERT语句
INSERT [INTO] tbl_name[(col_name,…)]
SELECT … ##select可以非常复杂,添加where条件等
语法:如果在表名后面列出了列名,那么列的数量和数据类型必须和子查询的select列表相匹配
示例:insert into stu_bak select sid,sname,aphonum from stu;在这里插入图片描述语句释义:stu_bak和stu表的数据类型和列的数量完全一致
Duplicates表示主键冲突的列:(主键冲突是主键上有重复的数据)
Records:表是插入多少行数据
示例2:
INSERT INTO penalties
SELECT paymentno + 100,playerno,payment_date,amount
FROM penalties
WHERE amount > (SELECT avg(amount) ##无关子查询(因为没有where条件,没有对外表访问)
FROM penalties);
语句释义:把那些罚款额大于平均罚款额的所有罚款添加到penalties表中
也可以把本表中的行再次添加到本表中。注意主键值不要重复

UPDATE语句
1.可以修改表中的数据
语法:
UPDATE [IGNORE] table_reference(表名)
SET col_name1=expr1 [, col_name2=expr2,],…
[WHERE where_condition]
[ORDER BY …]
[LIMIT row_count]
将满足WHERE条件的所有行的一个或多个列值改为新的值。没有WHERE子句则修改所有的行
2.在写update语句之前,可以先把select语句列出来需要更新的数据,对比着写出update语句
示例:
例1: 把95号球员的联盟会员号码改为2000
UPDATE players ##表名
SET leagueno = 2000 ##指定哪些列需要更新和更新的数据
WHERE playerno = 95; ##指定哪些行需要更新
共 1 行受到影响

例2: 把所有的罚款增加5%
UPDATE penalties
SET amount = amount*1.05;
共 8 行受到影响

例3: 把住在Stratford的球员的获胜局数设为0
UPDATE matches
SET won = 0
WHERE playerno IN(SELECT playerno
FROM players
WHERE town=‘Stratford’);
共 4 行受到影响在这里插入图片描述释义:先写出他们的select语句,对比写出update语句

3.update的其他写法(画图法)
通过画图的方法写update语句更容易理解
案例分析
CREATE TABLE players_data(
playerno INTEGER NOT NULL PRIMARY KEY,
number_mat INTEGER,
sum_penalties DECIMAL(7,2) ## 新建表,有三列
); ##新建表的每一列来自不同表的列中的数据(或者数据操作)

INSERT INTO players_data(playerno) ##从PLAYERS表中取出数据插入到新建表中
SELECT playerno FROM players; ##新建表的第一列数据已经插入完毕

UPDATE players_data pd ##更新,将新建表的第一列数据分别访问matches 表
SET number_mat = (
SELECT count(*)
FROM matches m
WHERE m.playerno = pd.playerno), ##number_mat列更新的数据为多表连接后行数
sum_penalties = (
SELECT sum(amount)
FROM penalties pen
WHERE pen.playerno = pd.playerno); ##sum_penalties表更新的数据为多表连接后的总数
语句释义:创建表players_data保存每个球员的编号、所参加比赛的次数,和所引起的罚款总数

4.update的注意事项
注意,在SET子句的子查询中,不允许访问要更新的表
案例分析
在每笔罚款中减去平均罚款额。以下写法不允许
UPDATE penalties
SET amount = amount - (SELECT avg(amount)
FROM penalties); ##set后,不允许出现要更新的表
错误代码: 1064

面对这种情况,我们可以使用变量的方法进行更新
SET @avg_amount := (SELECT avg(amount) FROM penalties); ##设置变量

UPDATE penalties
SET amount = amount - @avg_amount; ##使用变量

5.update语句中的order by 语句
UPDATE语句中可以使用ORDER BY子句,要求以排序的顺序来依次更新行。这在某些场景可能有用。例如,如果想要把所有罚款的罚款编号都加1,如果从罚款编号为1的行开始更新,要么就会发生主键值重复异常。如果从罚款编号最大的行开始更新,就没有问题
update语句是先找数据,在进行更新

示例:
UPDATE penalties
SET paymentno = paymentno + 1
ORDER BY paymentno DESC; ##降序排列后加1
语句释义:把所有罚款的编号增加1

6.update语句中的limit语句
UPDATE语句中可以使用LIMIT子句,指定一次更新的行数

示例:
UPDATE penalties
SET amount= amount *1.05
ORDER BY amount DESC, playerno ASC ##对penalties表的数据进行排序
LIMIT 4; ##前4个
语句释义:把4个最高的罚款额增加5%(罚款额相同则更新编号小的球员)

补充:IGNORE选项用于当UPDATE语句出错时,不显示错误消息

7.update更新多个表中的值
更新多个表中的值
MySQL允许我们使用1条UPDATE语句就更新两个或多个表中的行
语法:
UPDATE [IGNORE] table_references
SET col_name1=expr1 [, col_name2=expr2,],…
[WHERE where_condition]
其中, table_references可以使用任何合法的连接语法。不能使用ORDER BY和LIMIT子句

示例:
UPDATE matches m,teams t
SET m.won = 0,
t.playerno = 112
WHERE t.teamno = m.teamno
AND t.division = ‘first’;
语句释义:把一个first分级球队的所有比赛的获胜局数设为0,并把first分级球队的队长编号改为112
可以先使用select查看我们需要更改的数据(将两个表共有的且符合条件的显示出来)在这里插入图片描述补充:MySQL首先执行一个二表连接查询,从两个表中找到满足连接条件 t.teamno = m.teamno 的所有行,然后对这些行分别进行更新
使用一条语句更新多个表的优点是:要么两个表都更新,要么两个表都不更新

REPLACE语句
1.语句定义及语法
作用:替代已有的行
REPLACE语句是INSERT语句的一个变种。当添加新行时,如果主键值重复,那么就覆盖表中已有的行。如果没有主键值重复,则插入该行
语法:
REPLACE [INTO] tbl_name [(col_name,…)]
VALUES (expr,…),(…),…
或者
REPLACE [INTO] tbl_name [(col_name,…)]
SELECT …

示例:
REPLACE INTO players(playerno,NAME,initials,
sex,joined,street,town)
VALUES(611,‘john’,‘GG’,‘M’,1977,‘Green Way’, ‘Startford’);
语句释义: 添加一个新的球员。如果主键值已经存在,则覆盖该行

DELETE语句
1.delete说明及语法
delete语句只能一行一行的删,只能删除整行,不能删除某一行的某些列
语法:
DELETE [IGNORE] FROM tbl_name
[WHERE where_condition]
[ORDER BY …]
[LIMIT row_count]
从表中删除满足WHERE条件的所有行。没有WHERE条件,则删除表中的所有行

示例:
DELETE FROM penalties
WHERE playerno=44;
语句释义:删除44号球员的罚款

2.带子查询
注:在WHERE子句的子查询中,不允许访问要删除行的表
案例分析:
CREATE TABLE players_copy2
AS SELECT * FROM players; ##因为在WHERE子句的子查询中,不允许访问要删除行的表,所以我们可以创建一张和PLAYERS表一样的表

DELETE FROM players_copy1
WHERE joined > (
SELECT avg(joined)
FROM players_copy2 ## players_copy2 表和PLAYERS表一样
WHERE town = ‘Stratford’);
语句释义: 删除球员,条件是他们加入俱乐部的年份晚于来自于Stratford的球员加入俱乐部的平均年份
补充:面对较为复杂的删除,我们可以先用select语句将我们要删除的球员列出来,再将select *替换为delete即可

3.带ORDER BY子句和LIMIT子句
用在DELETE语句中的ORDER BY子句和LIMIT子句的含义和用在UPDATE语句中是类似的
示例:
DELETE FROM penalties
ORDER BY amount DESC,playerno ASC
LIMIT 4;
语句释义:删除4个最高的罚款

4.从多个表中删除行
语法:
DELETE [IGNORE] tbl_name[.] [, tbl_name[.]] …
FROM table_references
[WHERE where_condition]
如果FROM中的表有别名,在DELETE子句中只能使用表别名
示例:
DELETE teams, matches
FROM teams, matches
WHERE teams.teamno = matches.teamno
AND teams.teamno=3;
语句释义:从teams和matches表中删除所有3号球队的行; 两个表中满足连接条件teams.teamno = matches.teamno和过滤条件teams.teamno=3的所有行被删除

TRUNCATE语句
清空一张(大)表更有效的方法是使用TRUNCATE语句,它比DELETE快得多
原理:将表行尾的指针直接指向0,这样mysql认为该表数据已经清空,真实数据未清空,mysql后台程序或自动清理代表的数据
语法:
TRUNCATE [TABLE] tbl_name
示例:
Truncate table committee_members; ##将committee_members表清空

事务
1.事务:transaction
一个数据库事务由一条或者多条sql语句构成,它们形成一个逻辑的工作单元。这些sql语句要么全部执行成功,要么全部执行失败
事务是保证数据的完整性和一致性的重要手段
事务类型
DML事务:由一条或者多条DML语句构成
DDL事务:总是由一条DDL语句构成
DCL事务:总是由一条DCL语句构成

2.在MySQL中,系统变量@@autocommit默认是打开的,这意味着任何1条SQL语句都会开始一个事务,语句执行完后事务自动结束。实际使用中,应该使用SET语句来关闭自动提交,否则一个事务不可能由多条SQL语句构成
SHOW VARIABLES LIKE ‘%autocommit%’;
SET @@autocommit=0;
SHOW VARIABLES LIKE '%autocommit%’;

3.对于DDL(create、alter、drop等开头的语句)和DCL(grant、revoke语句)事务,在执行每条语句之前和之后,MySQL会自动执行一条COMMIT语句,因此事务是自动开始和结束的。自动提交打开或者关闭对这些事务没有影响
对于DML事务,在自动提交关闭的情况下,事务的开始分为隐式开始和显式开始:
隐式开始:程序的第一条DML语句执行时或者在COMMIT或ROLLBACK语句之后执行第一条DML语句时,自动开始一个新的事务
显式开始:发出STRAT TRANSACTION语句。该语句会自动关闭自动提交,当事务结束后,autocommit变量恢复到原来的值

4.DML事务的结束
COMMIT语句:成功提交。事务所做的全部工作被永久地保存到磁盘上
ROLLBACK语句:失败回滚。事务所做的全部工作被撤销,表中的数据不受事务操作的影响
其它事务控制语句
SAVEPOINT identifier :保存点命令,用来在事务中做一个标记,专门提供给rollback to语句使用
ROLLBACK TO [SAVEPOINT] identifier:回滚到保存点。专门用来撤销事务所做的部分工作:保存点之后所做的工作全部撤销。该语句并不结束事务

5.事务示例在这里插入图片描述ROLLBACK TO b; ##回滚到a保存点
ROLLBACK TO a; ##回滚到b保存点
ROLLBACK; ##回滚到事务开始之前

6.COMMIT 或 ROLLBACK 语句之前数据的状态
数据的修改都是在内存中进行的
通过查询表,当前用户(事务)能够查看DML操作的结果
其它用户(事务)不能查看当前用户(事务)所做的DML操作的结果。这叫做不允许脏读(dirty read)。脏读:一个事务读到了另一个事务未提交的数据。已修改但未提交的数据叫做赃数据
表中受影响的行被锁定,其它用户(事务)不能在受影响的行上修改数据

7.COMMIT或ROLLBACK语句之后数据的状态
COMMIT之后:
数据改变被写到数据库中
所有用户(事务)可以查看事务的结果
表中受影响行上的锁被释放,这些行现在可以被其它用户(事务)修改
事务中所有的保存点被删除
ROLLBACK之后:
数据改变被撤销
数据先前的状态被恢复
表中受影响行上的锁被释放


http://chatgpt.dhexx.cn/article/K96AZx9N.shtml

相关文章

MySQL基础——DDL、DML、DQL、DCL语句

当成功安装数据库之后,对于数据库进行的简单且基础的操作 打开数据库操作 1、在运行中输入services.msc 会打开如下界面 可以选择对MySQL进行开启或者关闭 2、也可以使用命令指示符 命令提示符要用管理员身份运行 输入命令 net start [自己设置的数据库名称] …

Oracle DB 使用DDL语句创建和管理表

• 对主要的数据库对象进行分类 • 查看表结构 • 列举列可以使用的数据类型 • 创建简单的表 • 说明创建表时如何创建约束条件 • 描述方案对象如何工作 • 数据库对象 – 命名规则 • CREATE TABLE语句: – 访问另一个用户的表 – DEFAULT选项 • 数据类型 • 约束条件概览…

C++值传递和引用传递的区别

c中参数传递的区别: 1.值传递: 可以想象改变的只是实参的“替身”的值,而实参本身不会被改变。 值传递:将实参的值传递给形参;形参是实参的“替身”,但与实参本质上不是“同一个人”,只是值复…

Java值传递和引用传递基础分析

(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/77688416冷血之心的博客) 一年前我总结过一篇博客:Java基础之引用(String,char[],Integer&#x…

C#中的值传递和引用传递

在C#语言中,传递参数的方式有两种:值传递和引用传递。 在介绍这两种参数传递方式我们先简单理解一下值类型和引用类型。 在C#语言中的char,int,short,long,byte,float,double,boolean类型都是值类型,另外enum枚举类型和struct结构类型也是值…

Python值传递和引用传递(详细分析)

目录 1. 形参与实参 2. Python的数据类型 3.Python变量及其赋值 3.1 不可变对象赋值 3.2 可变对象赋值 3.3 变量删除 3.4 变量赋值总结 4.Python函数的参数传递 4.1 参数传递定义 4.2 不可变对象的参数传递 4.3 可变对象的参数传递 5.总结 6 不可变与可变对象赋值对…

Java值传递和引用传递详细说明(详细分析)

1. 形参与实参 我们先来重温一组语法: 形参:方法被调用时需要传递进来的参数,如:func(int a)中的a,它只有在func被调用期间a才有意义,也就是会被分配内存空间,在方法func执行完成后&#xff0…

Java中是值传递和引用传递

值传递 / 引用传递 值传递:就是在方法调用的时候,实参是将自己的一份拷贝赋给形参,在方法内,对该参数值的修改不影响原来的实参。 引用传递:是在方法调用的时候,实参将自己的地址传递给形参,此…

Java的值传递和引用传递

Java的值传递和引用传递 值传递:对形参的修改不会影响到实参 。引用传递:对实参的修改能够影响到实参 **Java是值传递:如果是基本数据类型,就是复制一份值传递给形参;如果是引用类型,那就将引用复制一份&…

Java 值传递和引用传递

值传递:在调用函数的时候,将实际参数复制一份传递到函数中,这样在函数中对参数进行修改的时候,就不会影响到原来的实际参数 引用传递:在调用函数的时候,将实际参数的地址直接传递函数中,这样在函数中对参数进行修改的时候,就会影响到实际参数值传递 引用传递…

go 语言值传递和引用传递

值传递 普通的值传递 package main import "fmt" func main(){fmt.Println(Hello("hello"," fpp")); } func Hello(stringName string,stringName2 string)(string){return stringNamestringName2; }string类型是引用传递吗? package main i…

Java 的值传递和引用传递

一、概述 Java数据类型分为基本类型和引用类型。相应的,变量也有两种类型:基本类型和引用类型。 1️⃣基本类型的变量保存原始值,即它代表的值就是数值本身。包含: 整型:byte,short,int&#…

java值传递和引用传递(附实例)

java值传递和引用传递(附实例) 1.数据类型1.1 基本数据类型1.2 引用数据类型 2.形参与实参2.1 函数中使用2.2 调用 3.值传递和引用传递3.1 定义3.2 例子3.3 结论 观前提示: 本文所使用的IDEA版本为ultimate 2019.1,JDK版本为1.8.…

java中的值传递和引用传递

个人理解,可能会有错误之处,请仔细甄别,谨慎参考!如有错误或不同见解请指出! 值传递(Pass By Value或者Call By Value)是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。…

【JAVA】值传递与引用传递

一.声明 Java中没有引用传递 二.值传递和引用传递 值传递:就是在方法调用的时候,实参是将自己的一份拷贝赋给形参,在方法内,对该参数值的修改不影响原来的实参。 引用传递:是在方法调用的时候,实参将自…

值传递与引用传递详解

1、关于值传递 值传递:是指在调用函数时,将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,就不会影响到实际参数 如下图所示,当传递参数之前会将参数进行复制,函数中修改了参数&#xff0c…

值传递与引用传递的区别

一、值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 ​ 代码在内存中的执行流程: 1、首先加载main方法; ​ 2、接下来int number 100&#xff1…

什么是值传递,什么是引用传递?

1、什么是值传递,什么是引用传递? 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。引用传递(pass by referenc…

Java复习总结之快速区分值传递和引用传递

引言 为了搞清楚值传递和引用传递的区别,查阅了许多资料,加以自身理解,做出本篇博客用于记录。 概念 值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到…

华为应聘进展状态码解析(附加性格测试攻略)

多方查找咨询终于终于看到了自己的状态码,总结一下~ 性格测试攻略: https://blog.csdn.net/guomutian911/article/details/48915301 https://blog.csdn.net/twc829/article/details/51226358 https://blog.csdn.net/twc829/article/details/51226247 第三…