目錄
- 一、資料的插入(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.uj5u.com/shujuku/499167.html
標籤:SQL Server
