MySQL中update语句的深入分析

MySQL中update语句的深入分析

MySQL利用update语句更新表中的数据,update命令的格式如下:

UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [join tbl_name2 on tbl_name.col_name=tbl_name2.col_name]
    SET col_name1=expr1 [, col_name2=expr2 ...]
    [WHERE where_definition]
    [ORDER BY ...]
    [LIMIT row_count]

说明:
(1)tbl_name:要更新的表名;
(2)SET:指定要更新的字段;
(4)join:利用另一张表的数据更新当前表的数据;
(3)WHERE:通过条件指定要更新的行,如果省略WHERE子句,则更新所有的行;
(4)ORDER BY:按照被指定的顺序对行进行更新;
(5)LIMIT:限制更新的行数;
(6)IGNORE:在更新过程中出现错误,更新语句也不会中断。

注意:
(1)更新的数据必须满足表的约束条件;
(2)提供的数据必须与字段的数据类型匹配。

一、数据准备

创建emp(员工)表,并输入数据,代码如下:

create table emp(
    emp_id int primary key auto_increment comment '员工号',
    emp_name char(20) not null default '' comment '员工姓名',
    gender char(2) not null default '男' comment '性别',
    birth datetime not null default '1990-1-1' comment '出生日期',
    salary decimal(10,2) not null default 0 comment '工资',
    address varchar(200) not null default '' comment '通讯地址',
    dept_name char(20) comment '部门'
);

insert into emp(emp_name,gender,birth,salary,address,dept_name) 
values('张晓红','女','1980-1-23',5800,'河南省郑州市中原路10号','销售部'),
('张静静','女','1987-10-3',5400,'河南省新乡市平原路38号','销售部'),
('王云飞','男','1992-11-15',5600,'河南省新乡市人民路28号','销售部'),
('王鹏飞','男','1987-10-1',6800,'河南省新乡市东明大道12号','销售部'),
('王大鹏','男','1989-2-11',5900,'河南省郑州市东风路15号','销售部'),
('王萌萌','女','1986-12-30',5000,'河南省开封市五一路14号','财务部'),
('王大光','男','1988-11-8',6200,'河南省开封市八一路124号','财务部'),
('王小明','男','1998-1-3',4800,'河南省驻马店市雪松路128号','财务部'),
('王娜娜','女','1994-3-5',5200,'河南省驻马店市车站路2号','人事部'),
('刘云飞','男','1992-8-13',6800,'河南省南阳市民生路255号','人事部'),
('张陆军','男','1991-9-6',6200,'河南省南阳市张仲景路14号','人事部');

二、update命令的基本用法

mysql> select * from emp;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary  | address                              | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
|      1 | 张晓红    | 女     | 1980-01-23 00:00:00 | 5800.00 | 河南省郑州市中原路10号               | 销售部    |
|      2 | 张静静    | 女     | 1987-10-03 00:00:00 | 5400.00 | 河南省新乡市平原路38号               | 销售部    |
|      3 | 王云飞    | 男     | 1992-11-15 00:00:00 | 5600.00 | 河南省新乡市人民路28号               | 销售部    |
|      4 | 王鹏飞    | 男     | 1987-10-01 00:00:00 | 6800.00 | 河南省新乡市东明大道12号             | 销售部    |
|      5 | 王大鹏    | 男     | 1989-02-11 00:00:00 | 5900.00 | 河南省郑州市东风路15号               | 销售部    |
|      6 | 王萌萌    | 女     | 1986-12-30 00:00:00 | 5000.00 | 河南省开封市五一路14号               | 财务部    |
|      7 | 王大光    | 男     | 1988-11-08 00:00:00 | 6200.00 | 河南省开封市八一路124号              | 财务部    |
|      8 | 王小明    | 男     | 1998-01-03 00:00:00 | 4800.00 | 河南省驻马店市雪松路128号            | 财务部    |
|      9 | 王娜娜    | 女     | 1994-03-05 00:00:00 | 5200.00 | 河南省驻马店市车站路2号              | 人事部    |
|     10 | 刘云飞    | 男     | 1992-08-13 00:00:00 | 6800.00 | 河南省南阳市民生路255号              | 人事部    |
|     11 | 张陆军    | 男     | 1991-09-06 00:00:00 | 6200.00 | 河南省南阳市张仲景路14号             | 人事部    |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)

mysql> update emp set salary=salary+1000;   ---所有员工的工资增加1000元
Query OK, 11 rows affected (0.00 sec)
Rows matched: 11  Changed: 11  Warnings: 0

mysql> select * from emp;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary  | address                              | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
|      1 | 张晓红    | 女     | 1980-01-23 00:00:00 | 6800.00 | 河南省郑州市中原路10号               | 销售部    |
|      2 | 张静静    | 女     | 1987-10-03 00:00:00 | 6400.00 | 河南省新乡市平原路38号               | 销售部    |
|      3 | 王云飞    | 男     | 1992-11-15 00:00:00 | 6600.00 | 河南省新乡市人民路28号               | 销售部    |
|      4 | 王鹏飞    | 男     | 1987-10-01 00:00:00 | 7800.00 | 河南省新乡市东明大道12号             | 销售部    |
|      5 | 王大鹏    | 男     | 1989-02-11 00:00:00 | 6900.00 | 河南省郑州市东风路15号               | 销售部    |
|      6 | 王萌萌    | 女     | 1986-12-30 00:00:00 | 6000.00 | 河南省开封市五一路14号               | 财务部    |
|      7 | 王大光    | 男     | 1988-11-08 00:00:00 | 7200.00 | 河南省开封市八一路124号              | 财务部    |
|      8 | 王小明    | 男     | 1998-01-03 00:00:00 | 5800.00 | 河南省驻马店市雪松路128号            | 财务部    |
|      9 | 王娜娜    | 女     | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号              | 人事部    |
|     10 | 刘云飞    | 男     | 1992-08-13 00:00:00 | 7800.00 | 河南省南阳市民生路255号              | 人事部    |
|     11 | 张陆军    | 男     | 1991-09-06 00:00:00 | 7200.00 | 河南省南阳市张仲景路14号             | 人事部    |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)

mysql> update emp set salary=salary+1000 where dept_name='财务部';  ---'财务部'员工的工资增加1000元
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> select * from emp;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary  | address                              | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
|      1 | 张晓红    | 女     | 1980-01-23 00:00:00 | 6800.00 | 河南省郑州市中原路10号               | 销售部    |
|      2 | 张静静    | 女     | 1987-10-03 00:00:00 | 6400.00 | 河南省新乡市平原路38号               | 销售部    |
|      3 | 王云飞    | 男     | 1992-11-15 00:00:00 | 6600.00 | 河南省新乡市人民路28号               | 销售部    |
|      4 | 王鹏飞    | 男     | 1987-10-01 00:00:00 | 7800.00 | 河南省新乡市东明大道12号             | 销售部    |
|      5 | 王大鹏    | 男     | 1989-02-11 00:00:00 | 6900.00 | 河南省郑州市东风路15号               | 销售部    |
|      6 | 王萌萌    | 女     | 1986-12-30 00:00:00 | 7000.00 | 河南省开封市五一路14号               | 财务部    |
|      7 | 王大光    | 男     | 1988-11-08 00:00:00 | 8200.00 | 河南省开封市八一路124号              | 财务部    |
|      8 | 王小明    | 男     | 1998-01-03 00:00:00 | 6800.00 | 河南省驻马店市雪松路128号            | 财务部    |
|      9 | 王娜娜    | 女     | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号              | 人事部    |
|     10 | 刘云飞    | 男     | 1992-08-13 00:00:00 | 7800.00 | 河南省南阳市民生路255号              | 人事部    |
|     11 | 张陆军    | 男     | 1991-09-06 00:00:00 | 7200.00 | 河南省南阳市张仲景路14号             | 人事部    |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)

select * from emp order by salary desc;
 update emp set salary=salary+2000 order by salary desc limit 2;

三、update命令的使用技巧

(一)使用order by和limit更新特定记录

mysql> select * from emp order by salary desc;
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary  | address                              | dept_name |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
|      7 | 王大光    | 男     | 1988-11-08 00:00:00 | 8200.00 | 河南省开封市八一路124号              | 财务部    |
|      4 | 王鹏飞    | 男     | 1987-10-01 00:00:00 | 7800.00 | 河南省新乡市东明大道12号             | 销售部    |
|     10 | 刘云飞    | 男     | 1992-08-13 00:00:00 | 7800.00 | 河南省南阳市民生路255号              | 人事部    |
|     11 | 张陆军    | 男     | 1991-09-06 00:00:00 | 7200.00 | 河南省南阳市张仲景路14号             | 人事部    |
|      6 | 王萌萌    | 女     | 1986-12-30 00:00:00 | 7000.00 | 河南省开封市五一路14号               | 财务部    |
|      5 | 王大鹏    | 男     | 1989-02-11 00:00:00 | 6900.00 | 河南省郑州市东风路15号               | 销售部    |
|      1 | 张晓红    | 女     | 1980-01-23 00:00:00 | 6800.00 | 河南省郑州市中原路10号               | 销售部    |
|      8 | 王小明    | 男     | 1998-01-03 00:00:00 | 6800.00 | 河南省驻马店市雪松路128号            | 财务部    |
|      3 | 王云飞    | 男     | 1992-11-15 00:00:00 | 6600.00 | 河南省新乡市人民路28号               | 销售部    |
|      2 | 张静静    | 女     | 1987-10-03 00:00:00 | 6400.00 | 河南省新乡市平原路38号               | 销售部    |
|      9 | 王娜娜    | 女     | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号              | 人事部    |
+--------+-----------+--------+---------------------+---------+--------------------------------------+-----------+
11 rows in set (0.00 sec)

mysql>  update emp set salary=salary+2000 order by salary desc limit 2;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from emp order by salary desc;
+--------+-----------+--------+---------------------+----------+--------------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary   | address                              | dept_name |
+--------+-----------+--------+---------------------+----------+--------------------------------------+-----------+
|      7 | 王大光    | 男     | 1988-11-08 00:00:00 | 10200.00 | 河南省开封市八一路124号              | 财务部    |
|      4 | 王鹏飞    | 男     | 1987-10-01 00:00:00 |  9800.00 | 河南省新乡市东明大道12号             | 销售部    |
|     10 | 刘云飞    | 男     | 1992-08-13 00:00:00 |  7800.00 | 河南省南阳市民生路255号              | 人事部    |
|     11 | 张陆军    | 男     | 1991-09-06 00:00:00 |  7200.00 | 河南省南阳市张仲景路14号             | 人事部    |
|      6 | 王萌萌    | 女     | 1986-12-30 00:00:00 |  7000.00 | 河南省开封市五一路14号               | 财务部    |
|      5 | 王大鹏    | 男     | 1989-02-11 00:00:00 |  6900.00 | 河南省郑州市东风路15号               | 销售部    |
|      1 | 张晓红    | 女     | 1980-01-23 00:00:00 |  6800.00 | 河南省郑州市中原路10号               | 销售部    |
|      8 | 王小明    | 男     | 1998-01-03 00:00:00 |  6800.00 | 河南省驻马店市雪松路128号            | 财务部    |
|      3 | 王云飞    | 男     | 1992-11-15 00:00:00 |  6600.00 | 河南省新乡市人民路28号               | 销售部    |
|      2 | 张静静    | 女     | 1987-10-03 00:00:00 |  6400.00 | 河南省新乡市平原路38号               | 销售部    |
|      9 | 王娜娜    | 女     | 1994-03-05 00:00:00 |  6200.00 | 河南省驻马店市车站路2号              | 人事部    |
+--------+-----------+--------+---------------------+----------+--------------------------------------+-----------+
11 rows in set (0.00 sec)

(二)使用join关键字用其他表的数据更新当前表

举例:

create table stu(stu_id int primary key,
       stu_name char(20) not null default '',
       certificate_no char(20) not null default ''
);
insert into stu(stu_id,stu_name) values(10001,'张晓云'),(10002,'王云飞'),
(10003,'李大鹏'),(10004,'王大刚'),(10005,'张小倩'),(10006,'刘明明');

create table certificate(stu_id int primary key,
       certificate_type char(50) not null default '',
       certificate_no char(20) not null default ''
);

insert into certificate(stu_id,certificate_type,certificate_no) 
values(10001,'计算机二级office高级应用','Comp-2-25879'),
(10002,'计算机三级网络技术','Comp-3-25666'),
(10003,'英语四级','CET-4-12458'),
(10005,'英语四级','CET-4-55888');

--把certificate表中的证书编号填写到学生表中。
mysql> update stu s inner join certificate c on s.stu_id=c.stu_id
    -> set s.certificate_no=c.certificate_no;
Query OK, 4 rows affected (0.01 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql> select * from stu;
+--------+-----------+----------------+
| stu_id | stu_name  | certificate_no |
+--------+-----------+----------------+
|  10001 | 张晓云    | Comp-2-25879   |
|  10002 | 王云飞    | Comp-3-25666   |
|  10003 | 李大鹏    | CET-4-12458    |
|  10004 | 王大刚    |                |
|  10005 | 张小倩    | CET-4-55888    |
|  10006 | 刘明明    |                |
+--------+-----------+----------------+
6 rows in set (0.00 sec)

(三)使用子查询用其他表的数据更新当前表

mysql> update stu set certificate_no='';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 6  Changed: 4  Warnings: 0

mysql> select * from stu;
+--------+-----------+----------------+
| stu_id | stu_name  | certificate_no |
+--------+-----------+----------------+
|  10001 | 张晓云    |                |
|  10002 | 王云飞    |                |
|  10003 | 李大鹏    |                |
|  10004 | 王大刚    |                |
|  10005 | 张小倩    |                |
|  10006 | 刘明明    |                |
+--------+-----------+----------------+
6 rows in set (0.00 sec)

mysql> update stu set stu.certificate_no=
    -> (select certificate.certificate_no from certificate where certificate.stu_id=stu.stu_id)
    -> where exists (select 1 from certificate where certificate.stu_id=stu.stu_id);
Query OK, 4 rows affected (0.01 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql> select * from stu;
+--------+-----------+----------------+
| stu_id | stu_name  | certificate_no |
+--------+-----------+----------------+
|  10001 | 张晓云    | Comp-2-25879   |
|  10002 | 王云飞    | Comp-3-25666   |
|  10003 | 李大鹏    | CET-4-12458    |
|  10004 | 王大刚    |                |
|  10005 | 张小倩    | CET-4-55888    |
|  10006 | 刘明明    |                |
+--------+-----------+----------------+
6 rows in set (0.00 sec)

四、update使用中的误区

(一)一个update命令对一个字段多次更新

mysql> select * from emp where emp_id=9;
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary  | address                            | dept_name |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
|      9 | 王娜娜    | 女     | 1994-03-05 00:00:00 | 6200.00 | 河南省驻马店市车站路2号            | 人事部    |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
1 row in set (0.00 sec)

mysql> update emp set salary=salary-3000,salary=salary+4000 where emp_id=9;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from emp where emp_id=9;
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary  | address                            | dept_name |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
|      9 | 王娜娜    | 女     | 1994-03-05 00:00:00 | 7200.00 | 河南省驻马店市车站路2号            | 人事部    |
+--------+-----------+--------+---------------------+---------+------------------------------------+-----------+
1 row in set (0.00 sec)

说明:此命令相当于针对salary字段执行了两次更新。

(二)一次更新多个字段必须用逗号隔开,不能使用and连接

mysql> select * from emp where emp_id=7;
+--------+-----------+--------+---------------------+----------+-----------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary   | address                           | dept_name |
+--------+-----------+--------+---------------------+----------+-----------------------------------+-----------+
|      7 | 王大光    | 男     | 1988-11-08 00:00:00 | 10200.00 | 河南省开封市八一路124号           | 财务部    |
+--------+-----------+--------+---------------------+----------+-----------------------------------+-----------+
1 row in set (0.00 sec)

mysql> update emp set salary=5800 and birth='1988-10-1' and address='河南省开封市红旗路60号' where emp_id=7;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from emp where emp_id=7;
+--------+-----------+--------+---------------------+--------+-----------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary | address                           | dept_name |
+--------+-----------+--------+---------------------+--------+-----------------------------------+-----------+
|      7 | 王大光    | 男     | 1988-11-08 00:00:00 |   0.00 | 河南省开封市八一路124号           | 财务部    |
+--------+-----------+--------+---------------------+--------+-----------------------------------+-----------+
1 row in set (0.01 sec)

--该命令不能对emp表正确更新的原因是:把salary=后面的内容理解为一个逻辑表达式,
--返回逻辑值假(0),所以更新的结果为salary为0,即:
mysql> update emp set salary=(5800 and birth='1988-10-1', address='河南省开封市红旗路60号') where emp_id=7;
--正确的写法应该是:
mysql> update emp set salary=5800, birth='1988-10-1', address='河南省开封市红旗路60号' where emp_id=7;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from emp where emp_id=7;
+--------+-----------+--------+---------------------+---------+----------------------------------+-----------+
| emp_id | emp_name  | gender | birth               | salary  | address                          | dept_name |
+--------+-----------+--------+---------------------+---------+----------------------------------+-----------+
|      7 | 王大光    | 男     | 1988-10-01 00:00:00 | 5800.00 | 河南省开封市红旗路60号           | 财务部    |
+--------+-----------+--------+---------------------+---------+----------------------------------+-----------+
1 row in set (0.00 sec)
发布了44 篇原创文章 · 获赞 48 · 访问量 5404

猜你喜欢

转载自blog.csdn.net/weixin_44377973/article/details/103237009