我看到了那天的夕阳,美得如此骄艳,我便决定,追寻夕阳,拼尽余生。
上一章简单介绍了 MySQL插入数据(六),如果没有看过,请观看上一章
这一章节所用到的表,还是上一章的 user 进行讲解。
把一些记录都给删除了, 只留下这六条记录。
一. 更新数据命令 update 关键字
更新数据所用命令
update 表名 set 列名1=属性值1,列名2=属性值2...列名n=属性值n
[where 条件语句]
其中,老蝴蝶提示,一定要注意几点:
1 . 修改更新数据时, 用的是 set 设置 关键字。
2 . 列名和及后面对应的属性值 一定要对应,包括数据类型,长度。
3 . 可以一次性更新记录表里面的 多个属性值, 多个属性值之间是用 ,进行分隔。
4 . 更新时, 最好一定要加上 where 条件语句, 表示选择性更新。 如果不加的话,就表示更新全部的记录。 更新全部记录,很吓人的。
二. 更新一条记录的一个字段值
更新一条记录,如何唯一确定一条记录呢? 用主键。 后面的where 语句,用id=? 来进行确定。
更新单个字段值一般有以下两个情况:
1 . 更新成一个全新的值,与原来的值没有任何关联。
2 . 更新成一个与原来的值有关联的新值。 即将原来的值,通过某种规律,公式 变化成一个新的值。
二.一 更新成一个全新的值
如 将 id=1 的记录 的描述 description 更新成 ‘佛学爱好者’。 原来的值 ‘一个快乐的程序员’ 与现在要更新成的新值 ‘佛学爱好者’ 没有任何关联。
update user set description='佛学爱好者' where id=1;
可以看到:
Rows matched: 1 Changed: 1 Warnings: 0
匹配了一行, 改变了一行, 没有警告。 注意这个结果语句。
二.二 更新成一个与原来的值有关联的值
这种情况很常见, 如 在name字段的开始和末尾加上空格, 如截取name,只保留第一个值,即只留下姓, 如将 age 在原来的基础上 +2, 或者让 工资在原来的基础上增加10%. 这些都是与原来的值有关联的。
为了对这种情况加深印象,老蝴蝶分别 对字符串型的 name 和数字型的 age 分别举例说明。
二.二.一 字符串型 截取 只保留第一个值
将 id=3 的记录, 由原来的 name=‘岳泽霖’ 变成 name=‘岳’. 用 substr() 函数。
update user set name=substr(name,1,1) where id=3;
二.二.二 数字型 +2
将id=4 的年龄 age,在原来的基础上+2.
update user set age=age+2 where id=4;
其中, age=age+2 也可以写成 age+=2 这种形式。
二.三 更新某个字段时的其它情况
二.三.一 更新的值与原来的值相同 (不会报错,匹配但不运行)
如将 id=2的记录,由原来的性别 男 还改变成 男。
update user set sex='男' where id=2;
注意:
Rows matched: 1 Changed: 0 Warnings: 0
匹配了一行, 但改变了0 行,警告 0 行。 也就是说,并没有改变 id=2 这条记录。
所以在 业务开发时,不建议 根据 update 的 改变行数 的返回结果 来确定 是否正确的执行了数据。
即,不能说:
int rowCount=userDao.updateNameById(user);
if(rowCount>0){
//正常
}else{
throws new DataBaseException();
}
这样是不太好的。 可以 在改变字段之前,判断一下, 要改变的值是否与数据库中已经存在的值一致。 如果一致,就提示 用户 ‘与原来的值相同,无法修改’ 如果不一致,才进行更新数据库。
二.三.二 更新主键 问题 (会报错)
如将 id=2 的记录 的id 主键,更新换成别的不存在的值,如7。 更新成已经存在的值,肯定会报主键重复的问题。
udpate user set id=7 where id=2;
单个主键时,更新主键会报错。
二.三.三 更新导致约束问题 (会报错)
如name 是非空约束,将id=1的记录 的name改成 null,
update user set name=null where id=1;
也包括外键约束,唯一约束等。 如果不造成约束问题,是可以正常修改的。
二.三.四 更新数据类型不一致(会报错)
如 age 是数字型, 将id=1的记录 的age 变成 ‘年龄’
update user set age='年龄' where id=1;
二.三.五 更新时找不到匹配的记录 (不会报错, 无匹配,无运行)
如更新 id=7的 name信息。 但是,表里面没有id=7的记录。
update user set name='岳泽霖' where id=7;
注意:
Rows matched: 0 Changed: 0 Warnings: 0
没有行 匹配到, 没有行改变, 也没有错误。
三. 更新一条记录的多个字段值
上面举例的都是只更新一个字段的, 这儿可以更新多个字段。
其中,更新多个字段 与更新一个字段基本相同,就是 n*一个字段。 每个字段也都有 更新成一个全新的值,更新成一个与原来的值有关联的值 两种情况,也都有主键 和约束等问题。
要保证 每一个字段都能够单独更新成功,这样多个字段才能更新成功。
如, 更新id=6 的 姓名,年龄和描述。
update user set name='岳泽霖',age=24,description='一个快乐的程序员' where id=6;
如果更新的是部分一致,部分不一致, 如 name与原先的相同,age不与原先的相同,同样也是会更新这条数据的。 只要不全都一样就行。
全都一样的话,是不会更新的。
四. 更新多条记录
更新多条记录,是将这一批次的或者说符合筛选条件的记录,按照统一的修改方式进行修改。
常见的有两种形式:
1 .有筛选条件的, 但筛选条件有多条。
2 . 无筛选条件,整个数据表所有记录更新。
四.一 有筛选条件更新
如 将 id>3 的记录, 姓名全部改成 岳泽霖, 年龄全部改为 24岁。
update user set name='岳泽霖',age=24 where id>3;
由于有一条记录 id=6 的名称和年龄一样, 所以没有改变。
Rows matched: 3 Changed: 2 Warnings: 0
四.二 无筛选条件,整个数据表更新 (不建议这么更新)
将所有的记录 的姓名都改成 老蝴蝶,年龄改成25 岁。
update user set name='老蝴蝶',age=25;
这种情况,是很不好的,所以在更新时,一定要带上条件。 即使是 全部更新,也最好是 where 1=1 .
五. 联表时选择更新
上面的更新,都是单个表进行更新。 其实,在更新时,也可以进行连表进行更新。 但不常用。
命令:
update 表A inner[left,right] join 表B [on 条件] set 表A列1=属性值1,表A列2=属性值2;
用上一章节 的 dept 表和 u 表 。 再多添加几条数据。
需求:(当然,这个例子老蝴蝶举得不恰当) 更新user表,令部门为 信息管理部的 员工 的姓名修改成 ‘新员工入职’
update u inner join dept on u.deptId=dept.id and dept.id=1 set u.name='新员工入职';
发现,可以正常的进行修改。 将部门编号为1的 员工进行联表修改了。
但一般不这么用。
直接 用
update u set name='新员工入职' where id=1;
不正好吗?
所以,一般 联表更新不常用。
六. 多主键时,更新主键的问题
前面老蝴蝶讲过, 在单条记录时,更新主键 id 会报错, 即 二.三.二 的内容。
但如果是联合主键时, 更新主键时,会怎么样呢?
如创建一个表 user_status 时, 里面有 userId,termid,organ_code, status 四个属性。 其中, userId,termid,organ_code 是联合主键。 即三个联合主键, 一个普通字段。
六.一 创建表 user_status
create table user_status(
userId int(11),
termid varchar(20),
organ_code varchar(10),
status int(3),
primary key(userId,termid,organ_code)
);
六.二 插入数据
insert into user_status values(1,'2019-10','C1',1),(2,'2019-10','C1',1),(1,'2019-09','C1',1),
(2,'2019-09','C1',1),(3,'2019-10','C2',2);
六.三 演示列不全都是主键时更新主键的情况
六.三.一 更新一个主键 (更新成功)
将第一条记录 1,‘2019-10’,‘C1’ 更新它的机构为 ‘C2’
update user_status set organ_code='C2' where userId=1 and termid='2019-10' and organ_code='C1';
六.三.二 更新两个主键 (更新成功)
将 1,‘2019-09’,‘C1’ 更新它的 期次和机构编号, 为’2019-11’,‘C3’
update user_status set termid='2019-11',organ_code='C3'
where userId=1 and termid='2019-09' and organ_code='C1';
六.三.三 更新三个主键,即全部更新主键 (更新成功)
将 2,‘2019-09’,‘C1’ 更新它的 员工编号,期次和机构编号, 为 5,‘2019-11’,‘C3’ .
update user_status set userId=5,termid='2019-11',organ_code='C3'
where userId=2 and termid='2019-09' and organ_code='C1';
是全部都可以更新的,只要主键不与已经存在的重复即可。
六.四 演示列全都是主键时更新主键的情况
发现,上面 user_status 表, 还有一个status 字段不属于主键, 现在将这个字段删除掉呢, 将这个表变成 只有 userId,termid,organ_code 三个字段,并且三个字段都是主键的情况。
会发生什么呢?
删除列 status ,并重新查询数据
alter table user_status drop column status;
六.四.一 更新一个主键 (更新成功)
将 5,‘2019-11’,‘C3’ 那一条数据更新, 只更新机构编号为 ‘C2’
update user_status set organ_code='C2' where userId=5 and termid='2019-11' and organ_code='C3';
六.四.二 更新两个主键 (更新成功)
将 1,‘2019-10’,‘C2’ 那一条数据更新, 更新 机构编号为 ‘C3’,期次为 ‘2019-12’
update user_status set termid='2019-12',organ_code='C3'
where userId=1 and termid='2019-10' and organ_code='C2';
六.四.三 更新三个主键,即全部更新主键
将 3,‘2019-10’,‘C2’ 那一条数据更新, 更新 员工编号为 6,期次为’2019-12’, 机构为 ‘C3’
update user_status set userId=6,termid='2019-12',organ_code='C3'
where userId=3 and termid='2019-10' and organ_code='C2';
发现,也全部都是成功的,只要不与已经存在的数据相同即可。
谢谢!!!