大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说SQL 如何插入、删除和更新数据「终于解决」,希望您对编程的造诣更进一步.

- 一、数据的插入(INSERT 语句的使用方法)
- 1.1 什么是 INSERT
- 1.2 INSERT 语句的基本语法
- 1.3 列清单的省略
- 1.4 插入 NULL
- 1.5 插入默认值
- 1.6 从其他表中复制数据
- 二、数据的删除(DELETE 语句的使用方法)
- 2.1 DROP TABLE 语句和 DELETE 语句
- 2.2 DELETE 语句的基本语法
- 2.3 指定删除对象的 DELETE 语句(搜索型 DELETE)
- 三、数据的更新(UPDATE 语句的使用方法)
- 3.1 UPDATE 语句的基本语法
- 3.2 指定条件的 UPDATE 语句(搜索型 UPDATE)
- 3.3 使用 NULL 进行更新
- 3.4 多列更新
本文将会给大家介绍 DBMS 中用来更新表中数据的方法。SQL 数据的更新处理大体可以分为插入(INSERT)、删除(DELETE)和更新(UPDATE)三类。本文将会对这三类更新方法进行详细介绍。
一、数据的插入(INSERT 语句的使用方法)
本节重点
使用
INSERT语句可以向表中插入数据(行)。原则上,INSERT语句每次执行一行数据的插入。将列名和值用逗号隔开,分别括在
()内,这种形式称为清单。对表中所有列进行
INSERT操作时可以省略表名后的列清单。插入
NULL时需要在VALUES子句的值清单中写入NULL。可以为表中的列设定默认值(初始值),默认值可以通过在
CREATE TABLE语句中为列设置DEFAULT约束来设定。插入默认值可以通过两种方式实现,即在
INSERT语句的VALUES子句中指定DEFAULT关键字(显式方法),或省略列清单(隐式方法)。使用
INSERT…SELECT可以从其他表中复制数据。
1.1 什么是 INSERT
SQL 如何对表进行创建、更新和删除操作 给大家介绍了用来创建表的 CREATE TABLE 语句。通过 CREATE TABLE 语句创建出来的表,可以被认为是一个空空如也的箱子。
只有把数据装入到这个箱子后,它才能称为数据库。用来装入数据的 SQL 就是 INSERT(插入)(图 1)。

图 1 INSERT(插入)的流程
本节将会和大家一起学习 INSERT 语句。
要学习 INSERT 语句,我们得首先创建一个名为 ProductIns 的表。请大家执行代码清单 1 中的 CREATE TABLE 语句。
该表除了为 sale_price 列(销售单价)设置了 DEFAULT 0 的约束之外,其余内容与之前使用的 Product(商品)表完全相同。
DEFAULT 0 的含义将会在随后进行介绍,大家暂时可以忽略。
代码清单 1 创建 ProductIns 表的 CREATE TABLE 语句
CREATE TABLE ProductIns
(product_id CHAR(4) NOT NULL,
product_name VARCHAR(100) NOT NULL,
product_type VARCHAR(32) NOT NULL,
sale_price INTEGER DEFAULT 0,
purchase_price INTEGER ,
regist_date DATE ,
PRIMARY KEY (product_id));
如前所述,这里仅仅是创建出了一个表,并没有插入数据。接下来,我们就向 ProductIns 表中插入数据。
1.2 INSERT 语句的基本语法
SQL 如何对表进行创建、更新和删除操作 中讲到向 CREATE TABLE 语句创建出的 Product 表中插入数据的 SQL 语句时,曾介绍过 INSERT 语句的使用示例,但当时的目的只是为学习 SELECT 语句准备所需的数据,并没有详细介绍其语法。
下面就让我们来介绍一下 INSERT 语句的语法结构。
INSERT 语句的基本语法如下所示。
语法 1 INSERT 语句
INSERT INTO <表名> (列1, 列2, 列3, ……) VALUES (值1, 值2, 值3, ……);
例如,我们要向 ProductIns 表中插入一行数据,各列的值如下所示。
| product_id(商品编号) | product_name(商品名称) | product_type(商品种类) | sale_price(销售单价) | purchase_price(进货单价) | regist_date(登记日期) |
|---|---|---|---|---|---|
| 0001 | T 恤衫 | 衣服 | 1000 | 500 | 2009-09-20 |
此时使用的 INSERT 语句可参见代码清单 2。
代码清单 2 向表中插入一行数据
INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
VALUES ("0001", "T恤衫", "衣服", 1000, 500, "2009-09-20");
由于 product_id 列(商品编号)和 product_name 列(商品名称)是字符型,所以插入的数据需要像 "0001" 这样用单引号括起来。日期型的 regist_date(登记日期)列也是如此 [1]。
将列名和值用逗号隔开,分别括在 () 内,这种形式称为清单。代码清单 2 中的 INSERT 语句包含如下两个清单。
A:列清单→(product_id, product_name, product_type, sale_price, purchase_price, regist_date)
B:值清单→("0001", "T恤衫", "衣服", 1000, 500,"2009-09-20")
当然,表名后面的列清单和 VALUES 子句中的值清单的列数必须保持一致。如下所示,列数不一致时会出错,无法插入数据 [2]。
-- VALUES子句中的值清单缺少一列
INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
VALUES ("0001", "T恤衫", "衣服", 1000, 500);
此外,原则上,执行一次 INSERT 语句会插入一行数据 [3]。因此,插入多行时,通常需要循环执行相应次数的 INSERT 语句。
法则 1
原则上,执行一次
INSERT语句会插入一行数据。
专栏
多行 INSERT
法则 1 中介绍了“执行一次
INSERT语句会插入一行数据”的原则。虽然在大多数情况下该原则都是正确的,但它也仅仅是原则而已,其实很多 RDBMS 都支持一次插入多行数据,这样的功能称为多行
INSERT(multi row INSERT)。其语法请参见代码清单 A,将多条
VALUES子句通过逗号进行分隔排列。代码清单 A 通常的 INSERT 和多行 INSERT
-- 通常的INSERT INSERT INTO ProductIns VALUES ("0002", "打孔器", "办公用品", 500, 320, "2009-09-11"); INSERT INTO ProductIns VALUES ("0003", "运动T恤", "衣服", 4000, 2800, NULL); INSERT INTO ProductIns VALUES ("0004", "菜刀", "厨房用具", 3000, 2800, "2009-09-20"); -- 多行INSERT (Oracle以外) INSERT INTO ProductIns VALUES ("0002", "打孔器", "办公用品", 500, 320, "2009-09-11"), ("0003", "运动T恤", "衣服", 4000, 2800, NULL), ("0004", "菜刀", "厨房用具", 3000, 2800, "2009-09-20");该语法很容易理解,并且减少了书写语句的数量,非常方便。但是,使用该语法时请注意以下几点。
首先,
INSERT语句的书写内容及插入的数据是否正确。若不正确会发生INSERT错误,但是由于是多行插入,和特定的单一行插入相比,想要找出到底是哪行哪个地方出错了,就变得十分困难。其次,多行
INSERT的语法并不适用于所有的 RDBMS。该语法适用于 DB2、SQL、SQL Server、PostgreSQL 和 MySQL,但不适用于 Oracle。特定的 SQL
Oracle 使用如下语法来巧妙地完成多行
INSERT操作。-- Oracle中的多行INSERT INSERT ALL INTO ProductIns VALUES ("0002", "打孔器", "办公用品", 500, 320, "2009-09-11") INTO ProductIns VALUES ("0003", "运动T恤", "衣服", 4000, 2800, NULL) INTO ProductIns VALUES ("0004", "菜刀", "厨房用具", 3000, 2800, "2009-09-20") SELECT * FROM DUAL;
DUAL是 Oracle 特有(安装时的必选项)的一种临时表。因此“SELECT * FROM DUAL”部分也只是临时性的,并没有实际意义。在书写没有参照表的
SELECT语句时,写在FROM子句中的表。它并没有实际意义,也不保存任何数据,同时也不能作为INSERT和UPDATE的对象。
1.3 列清单的省略
对表进行全列 INSERT 时,可以省略表名后的列清单。这时 VALUES 子句的值会默认按照从左到右的顺序赋给每一列。因此,代码清单 3 中的两个 INSERT 语句会插入同样的数据。
代码清单 3 省略列清单
-- 包含列清单
INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
VALUES ("0005", "高压锅", "厨房用具", 6800, 5000, "2009-01-15");
-- 省略列清单
INSERT INTO ProductIns VALUES ("0005", "高压锅", "厨房用具", 6800, 5000, "2009-01-15");
1.4 插入 NULL
INSERT 语句中想给某一列赋予 NULL 值时,可以直接在 VALUES 子句的值清单中写入 NULL。
例如,要向 purchase_price 列(进货单价)中插入 NULL,就可以使用代码清单 4 中的 INSERT 语句。
代码清单 4 向 purchase_price 列中插入 NULL
INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
VALUES ("0006", "叉子", "厨房用具", 500, NULL, "2009-09-20");
但是,想要插入 NULL 的列一定不能设置 NOT NULL 约束。向设置了 NOT NULL 约束的列中插入 NULL 时,INSERT 语句会出错,导致数据插入失败。
插入失败指的是希望通过 INSERT 语句插入的数据无法正常插入到表中,但之前已经插入的数据并不会被破坏 [4]。
1.5 插入默认值
我们还可以向表中插入默认值(初始值)。可以通过在创建表的 CREATE TABLE 语句中设置 DEFAULT 约束来设定默认值。
本文开头创建的 ProductIns 表的定义部分请参见代码清单 5。其中 DEFAULT 0 就是设置 DEFAULT 约束的部分。像这样,我们可以通过“DEFAULT <默认值>”的形式来设定默认值。
代码清单 5 创建 ProductIns 表的 CREATE TABLE 语句(节选)
CREATE TABLE ProductIns
(product_id CHAR(4) NOT NULL,
(略)
sale_price INTEGER DEFAULT 0, -- 销售单价的默认值设定为0;
(略)
PRIMARY KEY (product_id));
如果在创建表的同时设定了默认值,就可以在 INSERT 语句中自动为列赋值了。默认值的使用方法通常有显式和隐式两种。
-
通过显式方法插入默认值
在
VALUES子句中指定DEFAULT关键字(代码清单 6)。代码清单 6 通过显式方法设定默认值
INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date) VALUES ("0007", "擦菜板", "厨房用具", DEFAULT, 790, "2009-04-28");这样一来,RDBMS 就会在插入记录时自动把默认值赋给对应的列。
我们可以使用
SELECT语句来确认通过INSERT语句插入的数据行。-- 确认插入的数据行; SELECT * FROM ProductIns WHERE product_id = "0007";因为
sale_price列(销售单价)的默认值是0,所以sale_price列被赋予了值0。执行结果:
product_id | product_name | product_type | sale_price | purchase_price | regist_date -----------+--------------+--------------+------------+----------------+---------- 0007 | 擦菜板 | 厨房用具 | 0 | 790 | 2008-04-28 -
通过隐式方法插入默认值
插入默认值时也可以不使用
DEFAULT关键字,只要在列清单和VALUES中省略设定了默认值的列就可以了。我们可以像代码清单 7 那样,从
INSERT语句中删除sale_price列(销售单价)。代码清单 7 通过隐式方法设定默认值

这样也可以给
sale_price赋上默认值0。那么在实际使用中哪种方法更好呢?笔者建议大家使用显式的方法。因为这样可以一目了然地知道
sale_price列使用了默认值,SQL 语句的含义也更加容易理解。说到省略列名,还有一点要说明一下。如果省略了没有设定默认值的列,该列的值就会被设定为
NULL。因此,如果省略的是设置了
NOT NULL约束的列,INSERT语句就会出错(代码清单 8)。请大家一定要注意。代码清单 8 未设定默认值的情况
-- 省略purchase_price列(无约束):会赋予“NULL” INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, regist_date) VALUES ("0008", "圆珠笔", "办公用品", 100, "2009-11-11"); -- 省略product_name列(设置了NOT NULL约束):错误! INSERT INTO ProductIns (product_id, product_type, sale_price,purchase_price, regist_date) VALUES ("0009", "办公用品", 1000, 500, "2009-12-12");法则 2
省略
INSERT语句中的列名,就会自动设定为该列的默认值(没有默认值时会设定为NULL)。
1.6 从其他表中复制数据
要插入数据,除了使用 VALUES 子句指定具体的数据之外,还可以从其他表中复制数据。下面我们就来学习如何从一张表中选取数据,复制到另外一张表中。
要学习该方法,我们首先得创建一张表(代码清单 9)。
代码清单 9 创建 ProductCopy 表的 CREATE TABLE 语句
-- 用来插入数据的商品复制表
CREATE TABLE ProductCopy
(product_id CHAR(4) NOT NULL,
product_name VARCHAR(100) NOT NULL,
product_type VARCHAR(32) NOT NULL,
sale_price INTEGER ,
purchase_price INTEGER ,
regist_date DATE ,
PRIMARY KEY (product_id));
ProductCopy(商品复制)表的结构与之前使用的 Product(商品)表完全一样,只是更改了一下表名而已。
接下来,就让我们赶快尝试一下将 Product 表中的数据插入到 ProductCopy 表中吧。代码清单 10 中的语句可以将查询的结果直接插入到表中。
代码清单 10 INSERT … SELECT 语句
-- 将商品表中的数据复制到商品复制表中
INSERT INTO ProductCopy (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
SELECT product_id, product_name, product_type, sale_price, purchase_price, regist_date
FROM Product;
执行该 INSERT … SELECT 语句时,如果原来 Product 表中有 8 行数据,那么 ProductCopy 表中也会插入完全相同的 8 行数据。
当然,Product 表中的原有数据不会发生改变。因此,INSERT … SELECT 语句可以在需要进行数据备份时使用(图 2)。

图 2 INSERT … SELECT 语句
-
多种多样的 SELECT 语句
该
INSERT语句中的SELECT语句,也可以使用WHERE子句或者GROUP BY子句等。目前为止学到的各种
SELECT语句也都可以使用 [5]。对在关联表之间存取数据来说,这是非常方便的功能。接下来我们尝试一下使用包含
GROUP BY子句的SELECT语句进行插入。代码清单 11 中的语句创建了一个用来插入数据的表。代码清单 11 创建 ProductType 表的 CREATE TABLE 语句
-- 根据商品种类进行汇总的表; CREATE TABLE ProductType (product_type VARCHAR(32) NOT NULL, sum_sale_price INTEGER , sum_purchase_price INTEGER , PRIMARY KEY (product_type));该表是用来存储根据商品种类(
product_type)计算出的销售单价合计值以及进货单价合计值的表。下面就让我们使用代码清单 12 中的
INSERT ... SELECT语句,从Product表中选取出数据插入到这张表中吧。代码清单 12 插入其他表中数据合计值的 INSERT … SELECT 语句
INSERT INTO ProductType (product_type, sum_sale_price, sum_purchase_price) SELECT product_type, SUM(sale_price), SUM(purchase_price) FROM Product GROUP BY product_type;通过
SELECT语句对插入结果进行确认,我们发现ProductType表中插入了以下 3 行数据。-- 确认插入的数据行 SELECT * FROM ProductType;执行结果:
product_type | sum_sale_price | sum_purchase_price --------------+-----------------+-------------------- 衣服 | 5000 | 3300 办公用品 | 600 | 320 厨房用具 | 11180 | 8590法则 3
INSERT语句的SELECT语句中,可以使用WHERE子句或者GROUP BY子句等任何 SQL 语法(但使用ORDER BY子句并不会产生任何效果)。
二、数据的删除(DELETE 语句的使用方法)
本节重点
如果想将整个表全部删除,可以使用
DROP TABLE语句,如果只想删除表中全部数据,需使用DELETE语句。如果想删除部分数据行,只需在
WHERE子句中书写对象数据的条件即可。通过WHERE子句指定删除对象的DELETE语句称为搜索型DELETE语句。
2.1 DROP TABLE 语句和 DELETE 语句
上一节我们学习了插入数据的方法,本节我们来学习如何删除数据。删除数据的方法大体可以分为以下两种。
① DROP TABLE 语句可以将表完全删除
② DELETE 语句会留下表(容器),而删除表中的全部数据
① 中的 DROP TABLE 语句我们已经在 SQL 如何对表进行创建、更新和删除操作 中学过了,此处再简单回顾一下。
DROP TABLE 语句会完全删除整张表,因此删除之后再想插入数据,就必须使用 CREATE TABLE 语句重新创建一张表。
反之,② 中的 DELETE 语句在删除数据(行)的同时会保留数据表,因此可以通过 INSERT 语句再次向表中插入数据。
本节所要介绍的删除数据,指的就是只删除数据的 DELETE 语句。
此外,我们在 SQL 如何对表进行创建、更新和删除操作 中也提到过,不管使用哪种方法,删除数据时都要慎重,一旦误删,想要恢复数据就会变得十分困难。
2.2 DELETE 语句的基本语法
DELETE 语句的基本语法如下所示,十分简单。
语法 2 保留数据表,仅删除全部数据行的 DELETE 语句
DELETE FROM <表名>;
执行使用该基本语法的 DELETE 语句,就可以删除指定的表中的全部数据行了。因此,想要删除 Product 表中全部数据行,就可以参照代码清单 13 来书写 DELETE 语句。
代码清单 13 清空 Product 表
DELETE FROM Product;
如果语句中忘了写 FROM,而是写成了“DELETE <表名>”,或者写了多余的列名,都会出错,无法正常执行,请大家特别注意。
前者无法正常执行的原因是删除对象不是表,而是表中的数据行(记录)。这样想的话就很容易理解了吧 [6]。
后者错误的原因也是如此。因为 DELETE 语句的对象是行而不是列,所以 DELETE 语句无法只删除部分列的数据。
因此,在 DELETE 语句中指定列名是错误的。当然,使用星号的写法(DELETE * FROM Product;)也是不对的,同样会出错。
法则 4
DELETE语句的删除对象并不是表或者列,而是记录(行)。
2.3 指定删除对象的 DELETE 语句(搜索型 DELETE)
想要删除部分数据行时,可以像 SELECT 语句那样使用 WHERE 子句指定删除条件。这种指定了删除对象的 DELETE 语句称为搜索型 DELETE [7]。
搜索型 DELETE 的语法如下所示。
语法 3 删除部分数据行的搜索型 DELETE
DELETE FROM <表名>
WHERE <条件>;
下面让我们以 Product(商品)表为例,来具体研究一下如何进行数据删除(表 1)。
表 1 Product 表
| product_id(商品编号) | product_name(商品名称) | product_type(商品种类) | sale_price(销售单价) | purchase_price(进货单价) | regist_date(登记日期) |
|---|---|---|---|---|---|
| 0001 | T 恤衫 | 衣服 | 1000 | 500 | 2009-09-20 |
| 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 |
| 0003 | 运动 T 恤 | 衣服 | 4000 | 2800 | |
| 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 |
| 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15 |
| 0006 | 叉子 | 厨房用具 | 500 | 2009-09-20 | |
| 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 |
| 0008 | 圆珠笔 | 办公用品 | 100 | 2009-11-11 |
假设我们要删除销售单价(sale_price)大于等于 4000 元的数据(代码清单 14)。上述表中满足该条件的是“运动 T 恤”和“高压锅”。
代码清单 14 删除销售单价(sale_price)大于等于 4000 元的数据
DELETE FROM Product
WHERE sale_price >= 4000;
WHERE 子句的书写方式与此前介绍的 SELECT 语句完全一样。
通过使用 SELECT 语句确认,表中的数据被删除了 2 行,只剩下 6 行。
-- 确认删除后的结果
SELECT * FROM Product;
执行结果:
product_id | product_name | product_type | sale_price | purchase_price | regist_date
-----------+--------------+--------------+------------+----------------+-----------
0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-09-20
0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11
0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20
0006 | 叉子 | 厨房用具 | 500 | | 2009-09-20
0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28
0008 | 圆珠笔 | 办公用品 | 100 | | 2009-11-11
法则 5
可以通过
WHERE子句指定对象条件来删除部分数据。
与 SELECT 语句不同的是,DELETE 语句中不能使用 GROUP BY、 HAVING 和 ORDER BY 三类子句,而只能使用 WHERE 子句。
原因很简单,GROUP BY 和 HAVING 是从表中选取数据时用来改变抽取数据形式的,而 ORDER BY 是用来指定取得结果显示顺序的。
因此,在删除表中数据时它们都起不到什么作用。
专栏
删除和舍弃
标准 SQL 中用来从表中删除数据的只有
DELETE语句。但是,很多数据库产品中还存在另外一种被称为TRUNCATE的语句。这些产品主要包括 Oracle、SQL Server、PostgreSQL、MySQL 和 DB2。
TRUNCATE是舍弃的意思,具体的使用方法如下所示。语法 A 只能删除表中全部数据的 TRUNCATE 语句
TRUNCATE <表名>;与
DELETE不同的是,TRUNCATE只能删除表中的全部数据,而不能通过WHERE子句指定条件来删除部分数据。也正是因为它不能具体地控制删除对象,所以其处理速度比
DELETE要快得多。实际上,
DELETE语句在 DML 语句中也属于处理时间比较长的,因此需要删除全部数据行时,使用TRUNCATE可以缩短执行时间。但是,产品不同需要注意的地方也不尽相同。
例如在 Oracle 中,把
TRUNCATE定义为 DDL,而不是 DML(因此,Oracle 中的TRUNCATE不能使用ROLLBACK。执行TRUNCATE的同时会默认执行COMMIT操作。)。使用
TRUNCATE时,请大家仔细阅读使用手册,多加注意。便利的工具往往还是会存在一些不足之处的。
三、数据的更新(UPDATE 语句的使用方法)
本节重点
使用
UPDATE语句可以更改(更新)表中的数据。更新部分数据行时可以使用
WHERE来指定更新对象的条件。通过WHERE子句指定更新对象的UPDATE语句称为搜索型UPDATE语句。
UPDATE语句可以将列的值更新为NULL。同时更新多列时,可以在
UPDATE语句的SET子句中,使用逗号分隔更新对象的多个列。
3.1 UPDATE 语句的基本语法
使用 INSERT 语句向表中插入数据之后,有时却想要再更改数据,例如“将商品销售单价登记错了”等的时候。
这时并不需要把数据删除之后再重新插入,使用 UPDATE 语句就可以改变表中的数据了。
和 INSERT 语句、DELETE 语句一样,UPDATE 语句也属于 DML 语句。通过执行该语句,可以改变表中的数据。其基本语法如下所示。
语法 4 改变表中数据的 UPDATE 语句
UPDATE <表名>
SET <列名> = <表达式>;
将更新对象的列和更新后的值都记述在 SET 子句中。
我们还是以 Product(商品)表为例,由于之前我们删除了“销售单价大于等于 4000 元”的 2 行数据,现在该表中只剩下了 6 行数据了(表 2)。
表 2 Product 表
| product_id(商品编号) | product_name(商品名称) | product_type(商品种类) | sale_price(销售单价) | purchase_price(进货单价) | regist_date(登记日期) |
|---|---|---|---|---|---|
| 0001 | T 恤衫 | 衣服 | 1000 | 500 | 2009-09-20 |
| 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 |
| 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 |
| 0006 | 叉子 | 厨房用具 | 500 | 2009-09-20 | |
| 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 |
| 0008 | 圆珠笔 | 办公用品 | 100 | 2009-11-11 |
接下来,让我们尝试把 regist_date 列(登记日期)的所有数据统一更新为“2009-10-10”。具体的 SQL 语句请参见代码清单 15。
代码清单 15 将登记日期全部更新为“2009-10-10”
UPDATE Product
SET regist_date = "2009-10-10";
表中的数据有何变化呢?我们通过 SELECT 语句来确认一下吧。
-- 确认更新内容
SELECT * FROM Product ORDER BY product_id;
执行结果:

此时,连登记日期原本为 NULL 的数据行(运动 T 恤)的值也更新为 2009-10-10 了。

3.2 指定条件的 UPDATE 语句(搜索型 UPDATE)
接下来,让我们看一看指定更新对象的情况。
更新数据时也可以像 DELETE 语句那样使用 WHERE 子句,这种指定更新对象的 UPDATE 语句称为搜索型 UPDATE 语句。
该语句的语法如下所示(与 DELETE 语句十分相似)。
语法 5 更新部分数据行的搜索型 UPDATE
UPDATE <表名>
SET <列名> = <表达式>
WHERE <条件>;
例如,将商品种类(product_type)为厨房用具的记录的销售单价(sale_price)更新为原来的 10 倍,请参见代码清单 16。
代码清单 16 将商品种类为厨房用具的记录的销售单价更新为原来的 10 倍
UPDATE Product
SET sale_price = sale_price * 10
WHERE product_type = "厨房用具";
我们可以使用如下 SELECT 语句来确认更新后的内容。
-- 确认更新内容
SELECT * FROM Product ORDER BY product_id;
执行结果:

该语句通过 WHERE 子句中的“product_type = "厨房用具"”条件,将更新对象限定为 3 行。
然后通过 SET 子句中的表达式 sale_price * 10,将原来的单价扩大了 10 倍。
SET 子句中赋值表达式的右边不仅可以是单纯的值,还可以是包含列的表达式。
3.3 使用 NULL 进行更新
使用 UPDATE 也可以将列更新为 NULL(该更新俗称为 NULL 清空)。
此时只需要将赋值表达式右边的值直接写为 NULL 即可。
例如,我们可以将商品编号(product_id)为 0008 的数据(圆珠笔)的登记日期(regist_date)更新为 NULL(代码清单 17)。
代码清单 17 将商品编号为 0008 的数据(圆珠笔)的登记日期更新为 NULL
UPDATE Product
SET regist_date = NULL
WHERE product_id = "0008";
-- 确认更新内容
SELECT * FROM Product ORDER BY product_id;
执行结果:

和 INSERT 语句一样,UPDATE 语句也可以将 NULL 作为一个值来使用。
但是,只有未设置 NOT NULL 约束和主键约束的列才可以清空为 NULL。
如果将设置了上述约束的列更新为 NULL,就会出错,这点与 INSERT 语句相同。
法则 6
使用
UPDATE语句可以将值清空为NULL(但只限于未设置NOT NULL约束的列)。
3.4 多列更新
UPDATE 语句的 SET 子句支持同时将多个列作为更新对象。
例如我们刚刚将销售单价(sale_price)更新为原来的 10 倍,如果想同时将进货单价(purchase_price)更新为原来的一半,该怎么做呢?
最容易想到的解决办法可能就是像代码清单 18 那样,执行两条 UPDATE 语句。
代码清单 18 能够正确执行的繁琐的 UPDATE 语句
-- 一条UPDATE语句只更新一列
UPDATE Product
SET sale_price = sale_price * 10
WHERE product_type = "厨房用具";
UPDATE Product
SET purchase_price = purchase_price / 2
WHERE product_type = "厨房用具";
虽然这样也能够正确地更新数据,但执行两次 UPDATE 语句不但有些浪费,而且增加了 SQL 语句的书写量。
其实,我们可以将其合并为一条 UPDATE 语句来处理。合并的方法有两种,请参见代码清单 19 和代码清单 20。
方法 ①:代码清单 19 将代码清单 18 的处理合并为一条 UPDATE 语句
-- 使用逗号对列进行分隔排列
UPDATE Product
SET sale_price = sale_price * 10,
purchase_price = purchase_price / 2
WHERE product_type = "厨房用具";
方法 ②:代码清单 20 将代码清单 18 的处理合并为一条 UPDATE 语句
-- 将列用()括起来的清单形式
UPDATE Product
SET (sale_price, purchase_price) = (sale_price * 10, purchase_price / 2)
WHERE product_type = "厨房用具";
执行上述两种 UPDATE 语句,都可以得到相同的结果:只有厨房用具的销售单价(sale_price)和进货单价(purchase_price)被更新了。
-- 确认更新内容
SELECT * FROM Product ORDER BY product_id;
执行结果:

当然,SET 子句中的列不仅可以是两列,还可以是三列或者更多。
需要注意的是第一种方法——使用逗号将列进行分隔排列(代码清单 19),这一方法在所有的 DBMS 中都可以使用。
但是第二种方法——将列清单化(代码清单 20),这一方法在某些 DBMS 中是无法使用的 [8]。因此,实际应用中通常都会使用第一种方法。
原文链接:https://www.developerastrid.com/sql/sql-insert-delete-update/
(完)
-
有关日期型的介绍,请参考 SQL 如何对表进行创建、更新和删除操作。 ↩︎
-
但是使用默认值时列数无需完全一致。相关内容将会在随后的“插入默认值”中进行介绍。 ↩︎
-
插入多行的情况,请参考专栏“多行
INSERT”。 ↩︎ -
不仅是
INSERT,DELETE和UPDATE等更新语句也一样,SQL 语句执行失败时都不会对表中数据造成影响。 ↩︎ -
但即使指定了
ORDER BY子句也没有任何意义,因为无法保证表内部记录的排列顺序。 ↩︎ -
与
INSERT语句相同,数据的更新也是以记录为基本单位进行的。下一节将要学习的UPDATE语句也是如此。 ↩︎ -
虽然“搜索型
DELETE”是正式用语,但实际上这种说法并不常用,而是简单地称为DELETE语句。 ↩︎ -
可以在 PostgreSQL 和 DB2 中使用。 ↩︎
原文地址:https://www.cnblogs.com/vin-c/archive/2022/06/09/16358278.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/5133.html